Existe-t-il un moyen de réécrire la structure de commande A && B || C | Dafin que B ou C soit canalisé dans D?
Avec la commande actuelle, seuls B ou C et D sont exécutés.
Par exemple:
Existe-t-il un moyen de réécrire la structure de commande A && B || C | Dafin que B ou C soit canalisé dans D?
Avec la commande actuelle, seuls B ou C et D sont exécutés.
Par exemple:
Réponses:
Oui, en bash, vous pouvez utiliser des parenthèses:
(A && B || C) | D
De cette façon, la sortie de A && B || Csera canalisée D.
sh:)
Ac'est à l'intérieur du sous-shell, cela comprend également A.)
Vous pouvez écrire ceci comme
if A; then B; else C; fi | D
Vous dites que vous voulez exécuter soit Bou C, mais que vous A && B || Cn'y arrivez pas. Si Aréussit, mais Bs'exécute et échoue, il s'exécute C.
Remarque 1: si vous pouvez garantir en quelque sorte que cela Bréussit toujours et que vous souhaitez vous en tenir à une version courte, alors j'opterais toujours pour
{ A && B || C; } | D
plus ( ... ), car ce dernier oblige inutilement à créer un nouveau sous-shell, qui peut ou non être optimisé.
Remarque 2: les deux formes supposent qu'il Ane produit aucune sortie, ce qui est vrai dans votre exemple mais pas nécessairement en général. Cela peut être évité en
A; if [ "$?" -eq 0 ]; then B; else C; fi | D
{ … }cela ne force pas la création d'un sous-shell à cause du tuyau? J'observe le comportement suivant: pgrep bashet pgrep bash | catet if true; then pgrep bash; fiet { pgrep bash; }ont une ligne de sortie; ( pgrep bash; )et ( pgrep bash; ) | catet { pgrep bash; } | catet if true; then pgrep bash; fi | catont deux lignes de sortie.
... | ...provoque la création d' un sous-shell, c'est inévitable. ( ... ), du moins en théorie, provoque la création d' un sous-shell supplémentaire qui { ...; }évite, mais c'est ce que je voulais dire par "peut ou non être optimisé": il est possible que dans ce cas particulier, le shell se rend compte que cela n'a pas d'importance, le l'effet serait le même.
La réponse de l'accepteur est correcte mais elle ne couvre pas le cas d'utilisation potentiel pour ne pas avoir la sortie de Acomme entrée de D. Pour y parvenir, vous aurez besoin d'une redirection de flux en Afonction de vos besoins.
Si vous souhaitez supprimer la sortie de Atoute façon:
{ A >/dev/null && B || C; } | DSi vous voulez voir la sortie de Asur le terminal:
{ A >/dev/tty && B || C; } | DSi vous avez besoin de la sortie de Acomme entrée d'une commande suivante, Evous aurez besoin d'un groupe de commandes supplémentaire et d'une redirection de flux:
{ { A >&3 && B || C; } | D; } 3>&1 | ESi tout cela vous semble trop mystérieux (comme c'est le cas pour moi), je vous recommande d'utiliser la variable shell spéciale pour l'état de sortie de Aet de travailler avec cela:
A
if [ $? -eq 0 ]; then
B
else
C
fi |
D
Si vous voulez être plus concis mais pas trop mystérieux, je suggère ceci:
A; { [ $? -eq 0 ] && B || C; } | D
(Voir aussi la dernière partie de la réponse de hvd que je n'ai pas remarquée lorsque j'ai écrit ma réponse d'origine.)
Asorti du pipeline.
A && (B || C) | D, si vous ne voulez pas que B, C ou D s'exécute lorsque A échoue