shell unix, obtenir le code de sortie avec enfant canalisé
-
27-09-2019 - |
Question
Soit s dire que je le fais dans un shell unix
$ some-script.sh | grep mytext
$ echo $?
cela me donnera le code de sortie de grep
mais comment puis-je obtenir le code de sortie de some-script.sh
EDIT
Supposons que l'opération de conduite est immuable. à savoir, je ne peux pas le briser et d'exécuter les deux commandes séparément
La solution
Il existe de multiples solutions, cela dépend de ce que vous voulez faire exactement.
La façon la plus simple et compréhensible serait d'envoyer la sortie vers un fichier, puis grep pour elle après avoir sauvegardé le code de sortie:
tmpfile=$(mktemp)
./some-script.sh > $tmpfile
retval=$?
grep mytext $tmpfile
rm tmpfile
Autres conseils
Un truc de la comp.unix.shell FAQ (# 13) explique comment l'utilisation du pipeline dans le shell Bourne devrait aider à accomplir ce que vous voulez:
You need to use a trick to pass the exit codes to the main shell. You can do it using a pipe(2). Instead of running "cmd1", you run "cmd1; echo $?" and make sure $? makes it way to the shell. exec 3>&1 eval ` # now, inside the `...`, fd4 goes to the pipe # whose other end is read and passed to eval; # fd1 is the normal standard output preserved # the line before with exec 3>&1 exec 4>&1 >&3 3>&- { cmd1 4>&-; echo "ec1=$?;" >&4 } | { cmd2 4>&-; echo "ec2=$?;" >&4 } | cmd3 echo "ec3=$?;" >&4
Si vous utilisez bash:
PIPESTATUS
An array variable (see Arrays) containing a list of exit status values from the processes in the most-recently-executed foreground pipeline (which may contain only a single command).
Il y a un utilitaire nommé mispipe
qui fait partie du paquet moreutils .
Il fait exactement cela: mispipe some-script.sh 'grep mytext'
Première approche, temporarly sauver l'état de sortie dans un certain fichier. Cette cause, vous devez créer en utilisant des accolades sous-shell:
(your_script.sh.pl.others; echo $? >/tmp/myerr)|\ #subshell with exitcode saving
grep sh #next piped commands
exitcode=$(cat /tmp/myerr) #restore saved exitcode
echo $exitcode #and print them
Une autre approche présentée par Randy ci-dessus, la mise en œuvre du code simplier:
some-script.sh | grep mytext
echo ${PIPESTATUS[0]} #print exitcode for first commands. tables are indexted from 0
son tout. les deux œuvres sous bash (je sais, bashizm). bonne chance :) les deux approches ne enregistre pas conduit à temporarly fichier physique, le code de sortie seulement.