59 votes

moyen approprié de détecter le code de sortie du shell lorsque l'option errexit est définie

Je préfère écrire du code shell solide, donc errexit & nounset est toujours défini.

Le code suivant s'arrêtera à la ligne bad_command

 #!/bin/bash
set -o errexit ; set -o nounset
bad_command # stop here
good_command

Je veux le capturer, voici ma méthode

 #!/bin/bash
set -o errexit ; set -o nounset
rc=1
bad_command && rc=0 # stop here
[ $rc -ne 0 ] && do_err_handle
good_command

Existe-t-il une méthode meilleure ou plus propre

Ma réponse:

 #!/bin/bash
set -o errexit ; set -o nounset
if ! bad_command ; then
  # error handle here
fi
good_command

55voto

rrauenza Points 186

Que dis-tu de ça? Si vous voulez le code de sortie réel...

 #!/bin/sh                                                                       
set -e

cat /tmp/doesnotexist && rc=$? || rc=$?                                         
echo exitcode: $rc        

cat /dev/null && rc=$? || rc=$?                                                 
echo exitcode: $rc   

Sortir:

 cat: /tmp/doesnotexist: No such file or directory
exitcode: 1
exitcode: 0

26voto

george Points 221

Continuez avec errexit. Cela peut aider à trouver des bogues qui pourraient autrement avoir des résultats imprévisibles (et difficiles à détecter).

 #!/bin/bash
set -o errexit ; set -o nounset

bad_command || do_err_handle
good_command

Ce qui précède fonctionnera bien. errexit ne nécessite que le passage de la ligne, comme vous le faites avec le bad_command && rc=0 . Par conséquent, ce qui précède avec le 'ou' n'exécutera do_err_handle que si bad_command échoue et, tant que do_err_handle n'échoue pas également, le script continuera.

7voto

yarolig Points 21

Continuez à écrire du code shell solide.

Vous le faites correctement si bad_command est vraiment une commande. Mais soyez prudent avec les appels de fonction if, while, ||, && ou !, car errexit ne fonctionnera pas là-bas. Cela peut être dangereux.

Si votre bad_command est en fait bad_function, vous devez écrire ceci :

 set -eu 

get_exit_code() {
    set +e
    ( set -e;
      "$@"
    )
    exit_code=$?
    set -e
}

...

get_exit_code bad_function

if [ "$exit_code" != 0 ]; then
    do_err_handle
fi

Cela fonctionne bien dans bash 4.0. Dans bash 4.2, vous n'obtenez que les codes de sortie 0 ou 1.

3voto

shellter Points 15304

D'accord avec les commentaires, donc si vous pouvez abandonner errexit vous pouvez facilement raccourcir votre code à

  bad_command || do_err_handle
 good_command

J'espère que ça aide.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X