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?
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
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
-andet-orde 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 comme1 && 1yields error messageThe 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$truedans 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
nosuchfileest transmise, parce que les erreurs sont envoyées à un flux séparé.
- cependant, la erreur information résultant du fichier inexistant
-
étant donné que
Get-ChildItem \, nosuchfilerenvoie 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
-andest$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
-andest 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
$truedans ce cas (qui se traduit parTruedans le terminal dans les systèmes de langue anglaise).
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}