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"
asgerhallas
fuente
Ver también ... stackoverflow.com/questions/3235850/…
SteveC
Posible duplicado de ¿Cómo ingresar un comando multilínea?
Michael Freidgeim

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.

Colin Pickard
fuente
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

BJHop
fuente
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"

bgmCoder
fuente
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
Aaron Jensen
fuente
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
)
Steven Penny
fuente
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"
Malo
fuente
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.

marca
fuente
-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"
Kirill Yunussov
fuente