Cómo dividir comandos largos en varias líneas en PowerShell


227

¿Cómo se toma un comando como el siguiente en PowerShell y se divide en varias líneas?

&"C:\Program Files\IIS\Microsoft Web Deploy\msdeploy.exe" -verb:sync -source:contentPath="c:\workspace\xxx\master\Build\_PublishedWebsites\xxx.Web" -dest:contentPath="c:\websites\xxx\wwwroot\,computerName=192.168.1.1,username=administrator,password=xxx"


Respuestas:


323

Carácter de retroceso final, es decir,

&"C:\Program Files\IIS\Microsoft Web Deploy\msdeploy.exe" `
-verb:sync `
-source:contentPath="c:\workspace\xxx\master\Build\_PublishedWebsites\xxx.Web" `
-dest:contentPath="c:\websites\xxx\wwwroot,computerName=192.168.1.1,username=administrator,password=xxx"

El espacio en blanco es importante. El formato requerido es Space`Enter.


1
Esto parece romper la funcionalidad del historial de comandos (flecha hacia arriba); ya que cada línea se muestra como un comando separado. ¿Hay alguna forma de evitar esto?
— Richard Ev

2
Si está ejecutando powershell 3 o superior, consulte github.com/lzybkr/psreadline: el recorrido del historial está corregido para las declaraciones de varias líneas.
— x0n

43
Se requiere el espacio en frente de la marca de retroceso # aprendido de la manera difícil
— Josh Graham

29
@ josh-graham Y NO debe haber ningún espacio (o comentario en línea) DESPUÉS de la marca de retroceso. # aprendido de la manera difícil
— RayLuo

1
Los backticks son frágiles (como se indica en los comentarios anteriores) y difíciles de encontrar al analizar o revisar un archivo. La respuesta de @StevenPenny es mejor si desea que sea más fácil depurar el código.
— mjd2

67

Otro método para pasar argumentos más limpios sería salpicar .

Defina sus parámetros y valores como una tabla hash como esta:

$params = @{ 'class' = 'Win32_BIOS';
             'computername'='SERVER-R2';
             'filter'='drivetype=3';
             'credential'='Administrator' }

Y luego llame a su comando como este:

Get-WmiObject @params

Documentos de Microsoft: acerca de las salpicaduras

TechNet Magazine 2011: Windows PowerShell: salpicaduras

Parece que funciona con Powershell 2.0 y versiones posteriores


55
¡Esto es maravilloso! Y se puede añadir parámetros de la siguiente manera: $params.add('name','Bob Newhart') ramblingcookiemonster.wordpress.com/2014/12/01/...
— bgmCoder

1
Los puntos y comas están bien pero son superfluos. Solo se requiere si hay varios valores por línea.
— Jim Abedul

38

Ah, y si tiene una cadena muy larga que desea dividir, digamos de HTML, puede hacerlo colocando un @a cada lado del exterior ", como este:

$mystring = @"
Bob
went
to town
to buy
a fat
pig.
"@

Obtienes exactamente esto:

Bob
went
to town
to buy
a fat
pig.

Y si está utilizando Notepad ++ , incluso se resaltará correctamente como un bloque de cadena.

Ahora, si desea que esa cadena también contenga comillas dobles, simplemente agréguelas de esta manera:

$myvar = "Site"
$mystring = @"
<a href="http://somewhere.com/somelocation">
Bob's $myvar
</a>
"@

Obtendría exactamente esto:

<a href="http://somewhere.com/somelocation">
Bob's Site
</a>

Sin embargo, si usa comillas dobles en esa cadena @ como esa, Notepad ++ no se da cuenta de eso y cambiará el color de la sintaxis como si no se hubiera citado o citado, según el caso.

Y lo que es mejor es esto: en cualquier lugar donde inserte una variable $, ¡SE interpreta! (Si necesita el signo de dólar en el texto, lo escapa con una marca de verificación como esta: `` $ not-a-variable`).

¡AVISO! Si no coloca la final "@al comienzo de la línea , fallará. ¡Me llevó una hora darme cuenta de que no podía sangrar eso en mi código!

Aquí está MSDN sobre el tema: Uso de Windows PowerShell "Here-Strings"


1
Buen truco, aunque si tengo una variable $ ... parece que no funciona. Me sale "el carácter no está permitido después de un encabezado de cadena aquí ..."
— tofutim

No creo que puedas romper un nombre de variable, solo una cadena.
— bgmCoder

19

Puede usar el operador de retroceso:

& "C:\Program Files\IIS\Microsoft Web Deploy\msdeploy.exe" `
    -verb:sync `
    -source:contentPath="c:\workspace\xxx\master\Build\_PublishedWebsites\xxx.Web" `
    -dest:contentPath="c:\websites\xxx\wwwroot\,computerName=192.168.1.1,username=administrator,password=xxx"

Todavía es un poco demasiado largo para mi gusto, así que usaría algunas variables bien nombradas:

$msdeployPath = "C:\Program Files\IIS\Microsoft Web Deploy\msdeploy.exe"
$verbArg = '-verb:sync'
$sourceArg = '-source:contentPath="c:\workspace\xxx\master\Build\_PublishedWebsites\xxx.Web"'
$destArg = '-dest:contentPath="c:\websites\xxx\wwwroot\,computerName=192.168.1.1,username=administrator,password=xxx"'

& $msdeployPath $verbArg $sourceArg $destArg

1
Me gustan los nombres de variables sobre otras sugerencias porque posiblemente sea la opción más legible para los expertos que no son de PowerShell. Si viera un tutorial / guía de configuración que usara salpicaduras, estaría totalmente perdido en lo que está sucediendo sin un sub-tutorial sobre salpicaduras. Del mismo modo, los backticks parecen frágiles y probablemente menos conocidos que las simples variables PS probadas y verdaderas.
— Josh Desmond el

13

Si tienes una función:

$function:foo | % Invoke @(
  'bar'
  'directory'
  $true
)

Si tiene un cmdlet :

[PSCustomObject] @{
  Path  = 'bar'
  Type  = 'directory'
  Force = $true
} | New-Item

Si tienes una aplicación:

{foo.exe @Args} | % Invoke @(
  'bar'
  'directory'
  $true
)

O

icm {foo.exe @Args} -Args @(
  'bar'
  'directory'
  $true
)

3

En PowerShell 5 y PowerShell 5 ISE, también es posible usar solo Shift+ Enterpara la edición multilínea (en lugar de los backticks estándar `al final de cada línea):

PS> &"C:\Program Files\IIS\Microsoft Web Deploy\msdeploy.exe" # Shift+Enter
>>> -verb:sync # Shift+Enter
>>> -source:contentPath="c:\workspace\xxx\master\Build\_PublishedWebsites\xxx.Web" # Shift+Enter
>>> -dest:contentPath="c:\websites\xxx\wwwroot,computerName=192.168.1.1,username=administrator,password=xxx"

0

Método Splat con cálculos

Si elige el método splat, tenga cuidado con los cálculos que se realizan con otros parámetros. En la práctica, a veces tengo que establecer variables primero y luego crear la tabla hash. Además, el formato no requiere comillas simples alrededor del valor clave o el punto y coma (como se mencionó anteriormente).

Example of a call to a function that creates an Excel spreadsheet

$title = "Cut-off File Processing on $start_date_long_str"
$title_row = 1
$header_row = 2
$data_row_start = 3
$data_row_end = $($data_row_start + $($file_info_array.Count) - 1)

# use parameter hash table to make code more readable
$params = @{
    title = $title
    title_row = $title_row
    header_row = $header_row
    data_row_start = $data_row_start
    data_row_end = $data_row_end
}
$xl_wksht = Create-Excel-Spreadsheet @params

Nota: La matriz de archivos contiene información que afectará la forma en que se llena la hoja de cálculo.


-1

Otra forma de dividir una cadena en varias líneas es colocar una expresión vacía en el medio de la cadena y dividirla en líneas:

cadena de muestra:

"stackoverflow stackoverflow stackoverflow stackoverflow stackoverflow"

roto a través de líneas:

"stackoverflow stackoverflow $(
)stackoverflow stack$(
)overflow stackoverflow"
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.