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
-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 comme1 && 1
yields 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$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é.
- cependant, la erreur information résultant du fichier inexistant
-
é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 parTrue
dans 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}