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.