Question Qu'est-ce que set -e signifie dans un script bash?


J'étudie le contenu de cette preinst fichier que le script exécute avant que ce paquet ne soit décompressé de son fichier d'archive Debian (.deb).

Le script a le code suivant:

#!/bin/bash
set -e
# Automatically added by dh_installinit
if [ "$1" = install ]; then
   if [ -d /usr/share/MyApplicationName ]; then
     echo "MyApplicationName is just installed"
     return 1
   fi
   rm -Rf $HOME/.config/nautilus-actions/nautilus-actions.conf
   rm -Rf $HOME/.local/share/file-manager/actions/*
fi
# End automatically added section

Ma première question concerne la ligne:

set -e

Je pense que le reste du script est assez simple: il vérifie si le gestionnaire de paquets Debian / Ubuntu exécute une opération d’installation. Si c'est le cas, il vérifie si mon application vient d'être installée sur le système. Si c'est le cas, le script imprime le message "MyApplicationName est juste installé" et prend fin (return 1 signifie que cela se termine par une "erreur", n'est-ce pas?).

Si l'utilisateur demande au système de paquet Debian / Ubuntu d'installer mon paquet, le script supprime également deux répertoires.

Est-ce exact ou est-ce que je manque quelque chose?


413
2017-10-27 19:06


origine


Réponses:


De help set :

  -e  Exit immediately if a command exits with a non-zero status.

Mais il est considéré comme une mauvaise pratique par certaines personnes (bash FAQ et des gens comme ceux qui écrivent cette FAQ sur irc freenode #bash), une meilleure utilisation:

trap 'do_something' ERR

courir do_something fonctionner quand des erreurs se produiront.

Voir http://mywiki.wooledge.org/BashFAQ/105


463
2017-10-27 19:39



set -e arrête l'exécution d'un script si une commande ou un pipeline a une erreur - ce qui est l'opposé du comportement du shell par défaut, qui est d'ignorer les erreurs dans les scripts. Type help set dans un terminal pour voir la documentation de cette commande intégrée.


61
2017-10-27 19:14



Selon bash - The Set Builtin manuel, si -e/errexit est défini, shell sort immédiatement si pipeline composé d'un seul commande simple, une liste ou une commande composée renvoie un statut non nul.

Par défaut, le statut de sortie d'un pipeline est le statut de sortie de la dernière commande du pipeline, sauf si le pipefail l'option est activée (désactivée par défaut).

Si c'est le cas, l'état de retour du pipeline de la dernière commande (la plus à droite) est de quitter avec un statut non nul, ou zéro si toutes les commandes se terminent avec succès.

Si vous souhaitez exécuter quelque chose en quittant, essayez de définir trap, par exemple:

trap onexit EXIT

onexit est votre fonction de faire quelque chose à la sortie, comme ci-dessous qui imprime le simple trace de la pile:

onexit(){ while caller $((n++)); do :; done; }

Il y a une option similaire -E/errtrace qui emprisonnerait plutôt ERR, par exemple:

trap onerr ERR

Exemples

Exemple d'état zéro:

$ true; echo $?
0

Exemple d'état non nul:

$ false; echo $?
1

Exemples d'état négatif:

$ ! false; echo $?
0
$ false || true; echo $?
0

Test avec pipefail être désactivé:

$ bash -c 'set +o pipefail -e; true | true | true; echo success'; echo $?
success
0
$ bash -c 'set +o pipefail -e; false | false | true; echo success'; echo $?
success
0
$ bash -c 'set +o pipefail -e; true | true | false; echo success'; echo $?
1

Test avec pipefail être activé:

$ bash -c 'set -o pipefail -e; true | false | true; echo success'; echo $?
1

33
2017-12-20 13:31



J'ai trouvé cette question en faisant une recherche sur Google, essayant de déterminer quel était le statut de sortie d’un script qui avait été abandonné en raison set -e. La réponse ne m'a pas semblé évidente; d'où cette réponse. Fondamentalement, set -e interrompt l'exécution d'une commande (par exemple un script shell) et renvoie le code d'état de sortie de la commande qui a échoué (c'est-à-dire le script interne, pas le script externe).

Par exemple, supposons que je possède un script shell outer-test.sh:

#!/bin/sh
set -e
./inner-test.sh
exit 62;

Le code pour inner-test.sh est:

#!/bin/sh
exit 26;

Quand je cours outer-script.sh à partir de la ligne de commande mon script externe se termine avec le code de sortie du script interne:

$ ./outer-test.sh
$ echo $?
26

25
2017-08-05 22:54