Quels sont les équivalents PowerShell des opérateurs && et | | / de Bash?

à Bash je peux facilement faire quelque chose comme

command1 && command2 || command3

, ce qui signifie pour exécuter command1 et si command1 réussit à exécuter command2 et si command1 ne parvient pas à exécuter command3.

Quel est l'équivalent en PowerShell?

21
demandé sur mklement0 2010-03-10 15:04:26

3 réponses

ce que Bash doit faire est de lancer implicitement le code de sortie des commandes à un booléen lorsqu'il est passé aux opérateurs logiques. PowerShell ne fait pas cela - mais une fonction peut être créée pour envelopper la commande et créer le même comportement:

> function Get-ExitBoolean($cmd) { & $cmd | Out-Null; $? }

( $? est un bool contenant le succès de la dernière sortie de code )

a donné deux fichiers de lot:

#pass.cmd
exit

et

#fail.cmd
exit /b 200

...le comportement peut être testé:

> if (Get-ExitBoolean .\pass.cmd) { write pass } else { write fail }
pass
> if (Get-ExitBoolean .\fail.cmd) { write pass } else { write fail }
fail

les opérateurs logiques doivent être évalués de la même manière qu'à Bash. Tout d'abord, définissez un alias:

> Set-Alias geb Get-ExitBoolean

Test:

> (geb .\pass.cmd) -and (geb .\fail.cmd)
False
> (geb .\fail.cmd) -and (geb .\pass.cmd)
False
> (geb .\pass.cmd) -and (geb .\pass.cmd)
True
> (geb .\pass.cmd) -or (geb .\fail.cmd)
True
8
répondu James Kolpack 2010-03-10 12:43:31

plusieurs années après que la question ait été posée pour la première fois, permettez-moi de résumer l'état des choses comme de PowerShell v5.1 :

  • Bash / cmd 's && et || opérateurs de contrôle ont PAS de PowerShell équivalents , et puisque vous ne pouvez pas définir des opérateurs dans PowerShell, il y a pas de bonnes solutions de contournement :

    • utilisez des commandes séparées (sur des lignes séparées ou séparées par ; ), et testez explicitement le statut de succès de chaque commande via la variable automatique $? , comme:

      command1 -arg1 -arg2; if ($?) { command2 -arg1 } # equivalent of &&

      command1 -arg1 -arg2; if (-not $?) { command2 -arg1 } # equivalent of ||

    • voir ci-dessous pourquoi les -and et -or de PowerShell sont généralement et non une solution.

  • il y avait parler de les ajouter un certain temps en arrière, mais il semble n'a jamais fait le haut de la liste.

    • Maintenant que PowerShell est passé en open source, un a été ouvert sur GitHub .
    • les jetons && et || sont actuellement réservés pour une utilisation future en PowerShell, donc il y a de l'espoir que la même syntaxe qu'en Bash puisse être implémentée.

      (En date du PSv5.1, en essayant quelque chose comme 1 && 1 yields error message The token '&&' is not a valid statement separator in this version. )

pourquoi les -and et -or de PowerShell ne remplacent pas && et || :

Bash opérateurs de contrôle && (court-circuiting logical AND) et || (court-circuiting logical OR) implicitement vérifier le statut de succès des commandes par leurs codes de sortie, sans interférer avec leurs flux de sortie ; par exemple:

ls / nosuchfile && echo 'ok'

Quel que soit ls sorties -- stdout (les fichiers dans / ) et stderr de sortie (le message d'erreur de la tentative d'accès au fichier inexistant nosuchfile ) -- est passé par , mais && vérifie le (invisible) code de sortie de la commande ls pour décider si la commande echo - le RHS de l'opérateur de contrôle && - doit être exécutée.

ls annonce le code de sortie 1 dans ce cas, signal échec -- parce que le fichier nosuchfile n'existe pas -- donc && décide que ls échec et, par l'application de court-circuit, décide que la "1519260920 de la commande" n'a pas besoin d'être exécuté.

Notez que c'est le code de sortie 0 qui signale le succès dans le monde de cmd.exe et bash , alors que tout nonzero code de sortie indique l'échec.

en d'autres termes: Bash's && et || opèrent complètement indépendamment des commandes" sortie et d'agir uniquement sur le succes des commandes.


les -and et -or de PowerShell , en revanche, n'agissent que sur la norme (succès) des commandes output , consume it et ensuite output only the Boolean result of the operation ; p.ex.:

(Get-ChildItem \, nosuchfile) -and 'ok'

ci-dessus:

  • utilise et consomme le success sortie (standard) -- la liste de \ -- et l'interprète comme un booléen ; une collection d'entrées non vide est considérée $true dans un contexte booléen, donc si il y a au moins une entrée, l'expression évalue à $true .

    • cependant, la erreur information résultant du fichier inexistant nosuchfile est transmise, parce que les erreurs sont envoyées à un flux séparé.
  • étant donné que Get-ChildItem \, nosuchfile renvoie la sortie de succès non vide, le LHS évalué à $true , donc -and évalue également le RHS, 'ok' , mais, encore une fois, consomme sa sortie et l'interprète comme un Booléen, qui, comme une chaîne non vide, évalue aussi pour $true .

  • ainsi, le résultat global de l'expression -and est $true , qui est (le seul succès) sortie .

le effet net est:

  • Le le succès de la sortie de part et d'autre de l'expression -and est consommé pendant l'évaluation et donc effectivement caché "1519790920 .

  • la seule sortie (réussie) de l'expression est son résultat booléen , qui est $true dans ce cas (qui se traduit par True dans le terminal dans les systèmes de langue anglaise).

16
répondu mklement0 2017-05-23 12:32:26

nous pouvons utiliser la méthode try catch finally au lieu d'utiliser && method dans powershell.

try {hostname} catch {echo err} finally {ipconfig /all | findstr bios}
0
répondu Cyberiron 2017-10-11 23:23:31