J'ai besoin d'exécuter un certain nombre de commandes shell canalisées à partir d'un script non BASH (à savoir un script PHP) comme ceux-ci:
command1 | command2 | command3
de sorte qu'en cas d' command1
échec avec un code de sortie différent de zéro, chaque autre commande échoue également. Jusqu'à présent, ce que j'ai trouvé est:
set -o pipefail && command1 | command2 | command3
Mais même s'il fonctionne correctement depuis le terminal, il produit ceci s'il est exécuté à partir du script:
sh: 1: set: option illégale -o pipefail
linux
command-line
shell
pipe
Desmond Hume
la source
la source
/bin/sh
n'aime passet -o pipefail
. Est-ce en faitbash
déguisé ou s'agit-il d'une coquille différente? Quandbash
est-il exécuté comme/bin/sh
, accepte-set -o pipefail
t- il ?/bin/sh set -o pipefail
il dit/bin/sh: 0: Can't open set
(même chose avecsudo
). J'espère que je l'ai testé correctement. Le système est Ubuntu 12./bin/sh -c "set -o pipefail"
; tel qu'il était, le shell essayait d'exécuter un script dans le répertoire courant appeléset
et il ne l'a pas trouvé./bin/sh -c "set -o pipefail"
ne fonctionne pas, cependantbash -c "set -o pipefail"
./bin/sh
qui ne reconnaît passet -o pipefail
. Par conséquent, vous devrez vous assurer que le script est exécuté par/bin/bash
au lieu de/bin/sh
. Ou, si vous êtes confiant, courageux - et probablement imprudent - changez/bin/sh
pour être un lien ou une copie de,/bin/bash
au lieu du shell auquel il est actuellement lié ou d'une copie. Si vous êtes sûr que/bin/sh
estbash
, alors vous utilisez un comportement quibash
n'expose pas lorsqu'il est exécuté comme/bin/sh
; utiliserbash
commebash
.Réponses:
À partir de la ligne de commande Bash, vous devrez appeler un sous-shell pour éviter d'
pipefail
être défini par la suite:Cela limiterait l'effet de l'
pipefail
option au sous-shell créé par les parenthèses(...)
.Un vrai exemple:
Si vous utilisez un appel shell explicite avec l'
-c
option, vous n'avez pas besoin d'un sous-shell, avecbash
ou avec unsh
alias pourbash
:Puisque votre
sh
n'accepte pas l'pipefail
option, je devrais supposer qu'il s'agit d'une version plus ancienne ou modifiée debash
- ou qu'il s'agit en fait d'un autre shell complètement.la source
$
dans la première partie une partie de la commande est-ce juste une invite shell? Essayé dans les deux sens, n'a pas vraiment fonctionné. Labash -c
manière fonctionne toujours, pas trop élégante cependant.Je ne sais pas pourquoi cela n'a pas été mentionné ci-dessus, mais il est possible de désactiver explicitement l'
pipefail
utilisationset +o pipefail
.Si vous exécutez un fragment et n'êtes pas sûr de ce qui est
pipefail
déjà défini, vous pouvez l'utiliser avec le sous-shell comme suggéré précédemment:la source
Vous pouvez utiliser $ (command1) combiné avec $? :
Imprime "abc"
Imprime "".
"[$? -eq 0] &&" signifie que la commande suivante n'est exécutée que si la précédente a réussi.
Cela ne répond pas à votre question mais c'est une solution à votre problème.
la source
command1 && command2 && command3