Cómo ingresar un comando de varias líneas

426

¿Es posible dividir una línea de comando de PowerShell en varias líneas?

En Visual Basic puedo usar el guión bajo ( _) para continuar el comando en la siguiente línea.

eXXL
fuente
3
La pregunta "por qué no barras invertidas" se trata muy bien en PowerShell en acción de Bruce Payette ; gran libro Bruce tiene un amplio conocimiento de la historia de los lenguajes de programación. Espero con ansias la V2 de este libro.
Jay Bazuzi
3
Duplicado de ... stackoverflow.com/questions/2608144/…
SteveC
1
Lo siento si no es un tema, pero si va a enviar el script con el shcomando, las convenciones de bash se mantienen para que pueda usar la barra invertida. En ese caso, su script también debe tener terminaciones de estilo Unix.
kon psych
simplemente use el carácter `para separar el comando en varias líneas
Asad Shakeel

Respuestas:

635

Puede usar un espacio seguido del acento grave (retroceso):

Get-ChildItem -Recurse `
  -Filter *.jpg `
  | Select LastWriteTime

Sin embargo, esto solo es necesario en los casos que se muestran arriba. Por lo general, obtiene una continuación de línea automática cuando un comando no puede completarse sintácticamente en ese punto. Esto incluye comenzar un nuevo elemento de canalización:

Get-ChildItem |
  Select Name,Length

funcionará sin problemas ya que después de que el |comando no se pueda completar ya que falta otro elemento de canalización. También abrir llaves o cualquier otro tipo de paréntesis permitirá la continuación de línea directamente:

$x=1..5
$x[
  0,3
] | % {
  "Number: $_"
}

Similar a la |coma también funcionará en algunos contextos:

1,
2

Sin embargo, tenga en cuenta que, de manera similar a la inserción automática de punto y coma de JavaScript , hay algunas cosas que se rompen de manera similar porque el salto de línea ocurre en un punto donde está precedido por una declaración válida:

return
  5

no trabajará.

Finalmente, las cadenas (en todas las variedades) también pueden extenderse más allá de una sola línea:

'Foo
bar'

Incluyen los saltos de línea dentro de la cadena, entonces.

Joey
fuente
44
Y no olvide mencionar que algunos otros tokens también actúan como continuadores de línea, por ejemplo, |y {.
Keith Hill
1
@Keith: Gracias, lo incluí. Probablemente eran demasiado obvios para mencionarlos ;-)
Joey
16
No, es bueno tener estos otros caracteres documentados para referencia futura.
Keith Hill
1
@JackDouglas: Puede tener un salto de línea directamente después del paréntesis de apertura, pero no dentro de la expresión antes del operador, aparentemente. Dicho esto, creo que eso es un descuido en la gramática.
Joey
10
La continuación de línea no funciona en el panel de comandos ISE, aparentemente.
Khouri Giordano
64

Me acabo de enterar de que no debe haber ningún carácter entre el tic de retroceso y el salto de línea. Incluso los espacios en blanco harán que el comando no funcione.

Neffets
fuente
10
Si bien esto técnicamente no es la respuesta a la pregunta, +1 porque esto es absolutamente esencial. Acabo de descubrir esto de la manera difícil, y seguramente evitaré el tick back en el desarrollo futuro siempre que sea posible.
Dave Markle
44
Por lo tanto, esencialmente no hay una forma sólida de romper una línea larga en Powershell. No es de extrañar que tiendo a ver esos scripts de PowerShell de 2 pantallas en todas partes . #ShakeMyHead
RayLuo
También estaba luchando con esto ... puede insertar un comentario en línea antes de la marca de retroceso para incluir un comentario, como este: Some-Command `-arg1 <# explicar arg 1 #>` -arg2 <# explicar arg 2 #>
joelsand
2
Urgh Esto hace que el código de PowerShell sea innecesariamente difícil de publicar en la documentación o en los sitios web, por temor a que el comando sea leído incorrectamente por un humano si se usa Shift + Enter, o se analiza mal en la línea de comando de ISE cuando se usa la marca de retroceso.
GuitarPicker
Voto negativo debido a la naturaleza del comentario (que no es una respuesta completa a la pregunta original).
CodeBreaker
38

En la mayoría de los lenguajes tipo C, soy deliberado acerca de colocar mis llaves donde creo que hacen que el código sea más fácil de leer.

El analizador de PowerShell reconoce cuando una declaración claramente no está completa y mira a la siguiente línea. Por ejemplo, imagine un cmdlet que toma un parámetro de bloque de script opcional:

    Get-Foo {............}

Si el bloque de script es muy largo, es posible que desee escribir:

    Get-Foo
    {
        ...............
        ...............
        ...............
    }

Pero esto no funcionará: el analizador verá dos declaraciones. El primero es Get-Fooy el segundo es un bloque de script. En cambio, escribo:

    Get-Foo {
        ...............
        ...............
        ...............
    }

Podría usar el carácter de continuación de línea (`) pero eso hace que el código sea difícil de leer e invita a los errores.

Como este caso requiere que la llave abierta esté en la línea anterior, sigo ese patrón en todas partes:

    if (condición) {
        .....
    }

Tenga en cuenta que las ifdeclaraciones requieren un bloque de secuencia de comandos en la gramática del lenguaje, por lo que el analizador buscará en la siguiente línea el bloque de secuencia de comandos, pero para mantener la coherencia, mantengo la llave abierta en la misma línea.

De manera similar, en el caso de tuberías largas, rompo después del carácter de tubería ( |):

    $ project.Items | 
        ? {$ _. Clave -eq "ProjectFile"} |
        % {$ _. Value} | 
        % {$ _. EvaluatedInclude} |
        % {
            .........
        }
Jay Bazuzi
fuente
¿cómo ify foreachy trytrabajo, entonces? permiten bloques de script en la siguiente línea ... esto significa que es posible que sea posible
Nacht - Reinstale a Monica
@Nacht: De la memoria oxidada: las declaraciones que requieren un bloque de script, según la gramática del lenguaje, analizarán una nueva línea para encontrar una. ¿Alguien puede confirmar?
Jay Bazuzi
2
@Nacht: "Pero esto no funcionará" se refería a situaciones en las que los parámetros adicionales son opcionales, que es la mayoría de los casos.
Jay Bazuzi
1
Ah, ya veo lo que quieres decir ahora. así que "if" y "foreach" no son cmdlets, son parte de la gramática, lo que obliga a mirar más allá de la siguiente línea. ¿no hay forma de permitir que una función definida por el usuario lea un bloque de script de la siguiente línea? Supongo que su respuesta anterior responde exactamente a esa pregunta.
Nacht - Restablece a Monica
29

Para ampliar la respuesta de cristobalito :

Supongo que está hablando en la línea de comandos: si está en un script, entonces una nueva línea> actúa como un delimitador de comandos.

En la línea de comando, use un punto y coma ';'

Por ejemplo:

Firme un script de PowerShell en la línea de comandos. No hay saltos de línea.

powershell -Command "&{$cert=Get-ChildItem –Path cert:\CurrentUser\my -codeSigningCert ; Set-AuthenticodeSignature -filepath Z:\test.ps1 -Cert $cert}
Alex
fuente
10
No es la respuesta a la pregunta, pero su respuesta respondió mi pregunta. :)
Frederik
1
Eso es interesante, pero es lo contrario de lo que OP estaba preguntando. OP quería dividir un solo comando en varias líneas; usted explicó cómo combinar varios comandos en una línea.
Daniel Yankowsky
17

En PowerShell y PowerShell ISE, también es posible usar Shift+ Enteral final de cada línea para la edición multilínea (en lugar de la tecla de retroceso estándar `).

Malo
fuente
2
Este es un gran consejo para editar cadenas de líneas múltiples aquí, que de otra manera son horribles para editar si no conoces el SHIFT-ENTERtruco.
dpw
1
Creo que este es el caso en la versión de consola de PowerShell solo cuando se usa el PSReadLinemódulo o un equivalente. En las funciones estándar de entrada de la consola de Windows, Entery Shift+Enterson funcionalmente equivalentes.
Bill_Stewart
@Bill_Stewart es cierto, funciona en la consola ISE sin PSReadline, pero no en el Host de la consola.
briantist
2
Para aclarar: 1) El PSReadlinemódulo funciona en el huésped consola única (no ISE). 2) Shift+Enterfunciona en el host de la consola solo cuando se usa PSReadline. 3) Shift+Entersiempre ha trabajado en el ISE. 4) Si usa el host de la consola sin PSReadline, Shift+Enteres funcionalmente equivalente a presionar Enter.
Bill_Stewart
2
¡Esta es la respuesta correcta, la que es aceptada y tiene 400 votos positivos es muy confusa e inútil!
FLICKER
4

Si está tratando de separar cadenas en varias líneas, puede usar el "+". Por ejemplo:

$header =    "Make," +

             "ComputerName," +

             "Model," +

             "Windows Version"

Se verá igual que:

$header = "Make,ComputerName,Model,Windows Version"
Steve Fellwock
fuente
2

Supongo que está hablando en la línea de comandos: si está en un script, entonces una nueva línea actúa como un delimitador de comandos.

En la línea de comando, use un punto y coma ';'

cristobalito
fuente
1
  1. Use un punto y coma ;para separar el comando
  2. Reemplace la barra diagonal inversa doble \\en cualquier barra diagonal inversa \.
  3. Úselo "'para pasar una dirección segura para cambiar el comando como "'RUTA'".

Este comando ps1 instala el certificado pfx de locale.

powershell -Command "$pfxPassword = ConvertTo-SecureString -String "12345678" -Force -AsPlainText ; Import-PfxCertificate -FilePath "'C:\\Program Files\\VpnManagement\\resources\\assets\\cert\\localhost.pfx'" Cert:\\LocalMachine\\My -Password $pfxPassword ; Import-PfxCertificate -FilePath "'C:\\Program Files\\VpnManagement\\resources\\assets\\cert\\localhost.pfx'" Cert:\\LocalMachine\\Root -Password $pfxPassword"
Musulmán Shahsavan
fuente
0
$scriptBlock = [Scriptblock]::Create(@'
  echo 'before'
  ipconfig /all
  echo 'after'
'@)

Invoke-Command -ComputerName AD01 -ScriptBlock $scriptBlock

la fuente
no usa comillas

Miguel
fuente
0

Simplemente use el carácter `para separar el comando en líneas múltiples

Asad Shakeel
fuente
0

Simplemente agregue un caso de esquina aquí. Puede ahorrarte 5 minutos. Si usa una cadena de acciones, debe poner "." al final de la línea, deje un espacio seguido de "" (retroceso). Descubrí esto de la manera difícil.

$yourString = "HELLO world! POWERSHELL!". `
                  Replace("HELLO", "Hello"). `
                  Replace("POWERSHELL", "Powershell")
Jian Huang
fuente