Bash tiene <(..)
para el proceso de sustitución. ¿Cuál es el equivalente de Powershell?
Sé que hay $(...)
, pero devuelve una cadena, mientras que <(..)
devuelve un archivo del que puede leer el comando externo, que es lo que espera.
Tampoco estoy buscando una solución basada en tubería, sino algo que pueda pegar en el medio de la línea de comando.
powershell
IttayD
fuente
fuente
Write-Output "The BITS service is $(Get-Service bits | select -ExpandProperty Stauts)"
para obtener el estado del servicio BITS sin cargarlo primero en una variable. En cuanto a la sustitución de procesos, esto no es exactamente lo mismo, pero aún podría resolver el problema que enfrentapsftp.exe
para las transferencias de SFTP: su-b
opción, debe proporcionar comandos para ejecutar en el servidor a través de un archivo , el cual es un inconveniente, si sólo desea ejecutar, por ejemplo,mget *
. Si PowerShell tuviera sustitución de proceso, podría hacer algo como esopsftp.exe -l user -p password somehost -b <( "mget *" )
.Respuestas:
Esta respuesta NO es para usted , si usted:
- rara vez, si es que alguna vez, necesita usar CLI externas (que generalmente vale la pena esforzarse - los comandos nativos de PowerShell se juegan mucho mejor juntos y no necesitan tal característica).
- No estoy familiarizado con el proceso de sustitución de Bash.
Esta respuesta ES para usted , si usted:
- utiliza con frecuencia CLI externas (ya sea por costumbre o por falta de alternativas (buenas) nativas de PowerShell), especialmente al escribir scripts.
- están acostumbrados y aprecian lo que puede hacer la sustitución del proceso de Bash.
- Actualización : ahora que PowerShell también es compatible con plataformas Unix, esta característica es de creciente interés; consulte esta solicitud de característica en GitHub, lo que sugiere que PowerShell implemente una característica similar a la sustitución de procesos.
En el mundo Unix, en Bash / Ksh / Zsh, una sustitución de proceso ofrece el tratamiento de la salida del comando como si fuera un archivo temporal que se limpia después de sí mismo; por ejemplo
cat <(echo 'hello')
, dondecat
ve la salida delecho
comando como la ruta de un archivo temporal que contiene la salida del comando .Si bien los comandos nativos de PowerShell no tienen una necesidad real de tal característica, puede ser útil cuando se trata de CLI externas .
Emular la función en PowerShell es engorroso , pero puede valer la pena si lo necesita con frecuencia.
Imagine una función llamada
cf
que acepte un bloque de script, ejecute el bloque y escriba su salida en una temp. archivo creado bajo demanda y devuelve la temp ruta del archivo ; p.ej:Este es un ejemplo simple que no ilustra bien la necesidad de tal característica. Quizás un escenario más convincente es el uso de
psftp.exe
transferencias SFTP: su uso por lotes (automatizado) requiere proporcionar un archivo de entrada que contenga los comandos deseados, mientras que dichos comandos se pueden crear fácilmente como una cadena sobre la marcha.Para ser tan ampliamente compatible con las utilidades externas como sea posible, la temp. archivo debe utilizar UTF-8 codificación sin BOM (marca de orden de bytes) de forma predeterminada, aunque se puede solicitar una lista de materiales UTF-8 con
-BOM
, si es necesario.Desafortunadamente, el aspecto de limpieza automática de las sustituciones de proceso no se puede emular directamente , por lo que se necesita una llamada de limpieza explícita ; la limpieza se realiza llamando
cf
sin argumentos :Para uso interactivo , puede automatizar la limpieza agregando la llamada de limpieza a su
prompt
función de la siguiente manera (laprompt
función devuelve la cadena de solicitud , pero también se puede usar para ejecutar comandos detrás de escena cada vez que se muestra la solicitud, similar a Bash$PROMPT_COMMAND
variable); para disponibilidad en cualquier sesión interactiva, agregue lo siguiente y la definición decf
abajo a su perfil de PowerShell:Para su uso en scripts , para garantizar que se realice la limpieza, el bloque que usa
cf
, potencialmente todo el script, debe estar envuelto en un bloquetry
/finally
, en el quecf
sin argumentos se requiere la limpieza:Aquí está la implementación : función avanzada
ConvertTo-TempFile
y su breve aliascf
:Nota : El uso de
New-Module
, que requiere PSv3 +, para definir la función a través de un módulo dinámico asegura que no pueda haber conflictos de variables entre los parámetros de la función y las variables referenciadas dentro del bloque de script pasado.Tenga en cuenta la capacidad de especificar opcionalmente una ruta de salida [archivo] y / o una extensión de nombre de archivo.
fuente
psftp.exe
, que es lo que me impulsó a escribirlo. Aunque es preferible hacer todo de forma nativa en PowerShell, eso no siempre es posible; invocar CLI externas de PowerShell ocurre y continuará sucediendo; Si se encuentra lidiando repetidamente con CLI que requieren la entrada de archivos que pueden (más) fácilmente construirse en la memoria / por otro comando, la función en esta respuesta puede facilitarle la vida.Cuando no se incluye entre comillas dobles,
$(...)
devuelve un Objeto de PowerShell (o más bien, lo que devuelve el código adjunto), evaluando primero el código adjunto. Esto debería ser adecuado para sus propósitos ("algo [I] puede pegarse en el medio de la línea de comando"), suponiendo que la línea de comando sea PowerShell.Puede probar esto conectando varias versiones a
Get-Member
, o incluso simplemente enviándolo directamente.Cuando se incluye entre comillas dobles, como habrá notado, `" $ (...) "simplemente devolverá una cadena.
De esta manera, si quisiera insertar, digamos, el contenido de un archivo directamente en una línea, podría usar algo como:
fuente
Get-Content <(Get-ChildItem)
Get-ChildItem | Get-Content
funciona perfectamente? ¿O de lo contrario podría intentarGet-Content (Get-ChildItem).FullName
el mismo efecto? Puede estar abordando esto desde una vista completamente influenciada por otro enfoque de secuencias de comandos.