Comment entrer une commande multiligne

427

Est-il possible de fractionner une ligne de commande PowerShell sur plusieurs lignes?

En Visual Basic, je peux utiliser le trait de soulignement ( _) pour continuer la commande dans la ligne suivante.

eXXL
la source
3
La question «pourquoi pas les contre-obliques» est bien couverte dans PowerShell en action de Bruce Payette ; grand livre. Bruce possède une vaste connaissance de l'histoire des langages de programmation. Dans l'attente de la V2 de ce livre.
Jay Bazuzi
3
Duplicate of ... stackoverflow.com/questions/2608144/…
SteveC
1
Désolé si hors sujet mais si vous devez soumettre le script avec la shcommande, les conventions bash sont valables pour que vous puissiez utiliser la barre oblique inverse. Dans ce cas, votre script doit également avoir des terminaisons de style Unix.
kon psych
utilisez simplement `caractère pour séparer la commande sur plusieurs lignes
Asad Shakeel

Réponses:

636

Vous pouvez utiliser un espace suivi de l'accent grave (backtick):

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

Cependant, cela n'est nécessaire que dans les cas indiqués ci-dessus. Habituellement, vous obtenez la continuation de ligne automatique lorsqu'une commande ne peut pas être terminée syntaxiquement à ce stade. Cela inclut le démarrage d'un nouvel élément de pipeline:

Get-ChildItem |
  Select Name,Length

fonctionnera sans problème car après la |commande, la commande ne peut pas être terminée car il manque un autre élément de pipeline. L'ouverture d'accolades ou tout autre type de parenthèses permettra également la continuation de la ligne directement:

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

Semblable à la |virgule, cela fonctionnera également dans certains contextes:

1,
2

Gardez à l'esprit, cependant, que pour l' insertion automatique des points-virgules de JavaScript , certaines choses sont également interrompues car le saut de ligne se produit à un point où il est précédé d'une instruction valide:

return
  5

ne fonctionnera pas.

Enfin, les chaînes (dans toutes les variétés) peuvent également s'étendre au-delà d'une seule ligne:

'Foo
bar'

Ils incluent alors les sauts de ligne dans la chaîne.

Joey
la source
4
Et n'oubliez pas de mentionner que certains autres jetons agissent également comme des continuateurs de ligne, par exemple |et {.
Keith Hill
1
@Keith: Merci, je l'ai inclus. Celles-ci étaient probablement trop évidentes pour être mentionnées ;-)
Joey
16
Non, c'est bien d'avoir ces autres caractères documentés pour référence future.
Keith Hill
1
@JackDouglas: Vous pouvez avoir un saut de ligne directement après la parenthèse ouvrante, mais pas dans l'expression avant l'opérateur, apparemment. Cela étant dit, je pense que c'est un oubli dans la grammaire.
Joey
10
Apparemment, la poursuite de la ligne ne fonctionne pas dans le volet de commande ISE.
Khouri Giordano
64

Je viens de découvrir qu'il ne doit y avoir aucun caractère entre la tique arrière et le saut de ligne. Même les espaces blancs empêcheront la commande de fonctionner.

Neffets
la source
10
Bien que ce ne soit pas techniquement la réponse à la question, +1 parce que c'est absolument essentiel. Je viens de découvrir cela à la dure, et j'éviterai sûrement le retour en arrière dans le développement futur dans la mesure du possible.
Dave Markle
4
Il n'y a donc essentiellement aucun moyen robuste de briser une longue file d'attente à Powershell. Pas étonnant que j'ai tendance à voir ces scripts PowerShell sur 2 écrans partout. #ShakeMyHead
RayLuo
Je me débattais aussi avec cela ... vous pouvez insérer un commentaire en ligne avant la coche arrière pour inclure un commentaire, comme ceci: Some-Command `-arg1 <# expliquer arg 1 #>` -arg2 <# expliquer arg 2 #>
joelsand
2
Urgh. Cela rend le code PowerShell inutilement difficile à publier dans la documentation ou les sites Web, de peur que la commande soit mal lue par un humain si vous utilisez Shift + Entrée, ou mal analysée dans la ligne de commande ISE lors de l'utilisation de la coche arrière.
GuitarPicker du
Vote négatif en raison de la nature du commentaire (qui n'est pas une réponse complète à la question d'origine).
CodeBreaker
38

Dans la plupart des langages de type C, je souhaite délibérément placer mes accolades là où je pense qu'elles rendent le code plus facile à lire.

L'analyseur de PowerShell reconnaît quand une instruction n'est clairement pas terminée et regarde la ligne suivante. Par exemple, imaginez une applet de commande qui accepte un paramètre de bloc de script facultatif:

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

si le bloc de script est très long, vous voudrez peut-être écrire:

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

Mais cela ne fonctionnera pas: l'analyseur verra deux déclarations. Le premier est Get-Fooet le second est un bloc de script. Au lieu de cela, j'écris:

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

Je pourrais utiliser le caractère de continuation de ligne (`) mais cela rend le code difficile à lire et invite les bogues.

Parce que ce cas nécessite que l'accolade ouverte soit sur la ligne précédente, je suis ce modèle partout:

    si (condition) {
        .....
    }

Notez que les ifinstructions nécessitent un bloc de script dans la grammaire du langage, donc l'analyseur recherchera la ligne suivante pour le bloc de script, mais pour des raisons de cohérence, je garde l'accolade ouverte sur la même ligne.

De même, dans le cas de longs pipelines, je casse après le caractère pipe ( |):

    $ project.Items | 
        ? {$ _. Key -eq "ProjectFile"} |
        % {$ _. Valeur} | 
        % {$ _. EvaluatedInclude} |
        % {
            .........
        }
Jay Bazuzi
la source
comment ça marche ifet foreachet tryalors? ils autorisent les blocs de script sur la ligne suivante ... cela signifie que cela peut être possible
Nacht - Réinstallez Monica
@Nacht: From rusty memory: les instructions qui nécessitent un bloc de script, selon la grammaire du langage, analyseront une nouvelle ligne pour en trouver une. Quelqu'un peut-il confirmer?
Jay Bazuzi
2
@Nacht: "Mais cela ne fonctionnera pas" faisait référence à des situations où les autres paramètres sont facultatifs, ce qui est le plus souvent le cas.
Jay Bazuzi
1
ah je vois ce que tu veux dire maintenant. donc "si" et "foreach" ne sont pas en fait des applets de commande - ils font tous partie intégrante de la grammaire, la forçant ainsi à passer à la ligne suivante. n'y a-t-il alors aucun moyen de laisser une fonction définie par l'utilisateur lire un bloc de script de la ligne suivante? Je suppose que votre réponse ci-dessus répond exactement à cette question.
Nacht - Rétablir Monica
29

Pour développer la réponse de cristobalito :

Je suppose que vous parlez sur la ligne de commande - si c'est dans un script, alors une nouvelle ligne> agit comme un délimiteur de commande.

Sur la ligne de commande, utilisez un point-virgule ';'

Par exemple:

Signez un script PowerShell sur la ligne de commande. Aucune rupture de ligne.

powershell -Command "&{$cert=Get-ChildItem –Path cert:\CurrentUser\my -codeSigningCert ; Set-AuthenticodeSignature -filepath Z:\test.ps1 -Cert $cert}
Alex
la source
10
Pas la réponse à la question, mais votre réponse a répondu à ma question. :)
Frederik
1
C'est intéressant, mais c'est le contraire de ce que demandait OP. OP voulait diviser une seule commande sur plusieurs lignes; vous avez expliqué comment combiner plusieurs commandes sur une seule ligne.
Daniel Yankowsky
17

Dans PowerShell et PowerShell ISE, il est également possible d'utiliser Shift+ Enterà la fin de chaque ligne pour l'édition multiligne (au lieu du backtick standard `).

Mauvais
la source
2
C'est une excellente astuce pour éditer des chaînes ici sur plusieurs lignes, qui sont autrement horribles à éditer si vous ne connaissez pas l' SHIFT-ENTERastuce.
dpw
1
Je pense que c'est le cas dans la version console de PowerShell uniquement lors de l'utilisation du PSReadLinemodule ou d'un équivalent. Dans les fonctions d'entrée de console Windows standard, Enteret Shift+Entersont fonctionnellement équivalentes.
Bill_Stewart
@Bill_Stewart true, cela fonctionne dans la console ISE sans PSReadline, mais pas dans l'hôte de la console.
briantist
2
Pour clarifier: 1) Le PSReadlinemodule fonctionne uniquement sur l' hôte de la console (pas ISE). 2) ne Shift+Enterfonctionne dans l'hôte de la console que lors de l'utilisation PSReadline. 3) Shift+Entera toujours travaillé dans l'ISE. 4) Si vous utilisez l'hôte de console sans PSReadline, cela Shift+Enteréquivaut fonctionnellement à appuyer sur Enter.
Bill_Stewart
2
c'est la bonne réponse, celle qui est acceptée et qui a 400 votes positifs est très déroutante et inutile !!
FLICKER
4

Si vous essayez de séparer des chaînes en plusieurs lignes, vous pouvez utiliser le "+". Par exemple:

$header =    "Make," +

             "ComputerName," +

             "Model," +

             "Windows Version"

Ressemblera à:

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

Je suppose que vous parlez sur la ligne de commande - si c'est dans un script, alors une nouvelle ligne agit comme un délimiteur de commande.

Sur la ligne de commande, utilisez un point-virgule ';'

cristobalito
la source
1
  1. Utilisez un point-virgule ;pour séparer la commande
  2. Remplacez la barre oblique inverse double \\sur toutes les barres obliques inverses \.
  3. Utilisez "'pour passer une adresse sûre pour changer de commande comme "'PATH'".

Cette commande ps1 installe le certificat pfx local.

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"
Shahsavan musulman
la source
0
$scriptBlock = [Scriptblock]::Create(@'
  echo 'before'
  ipconfig /all
  echo 'after'
'@)

Invoke-Command -ComputerName AD01 -ScriptBlock $scriptBlock

la source
n'utilise pas de guillemets

Mike
la source
0

Utilisez simplement `caractère pour séparer la commande sur plusieurs lignes

Asad Shakeel
la source
0

Ajoutez simplement un étui d'angle ici. Cela pourrait vous faire économiser 5 minutes. Si vous utilisez une chaîne d'actions, vous devez mettre "." à la fin de la ligne, laissez un espace suivi du "` "(backtick). Je l'ai découvert à la dure.

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