Que signifie set-e dans un script bash?

j'étudie le contenu de ce fichier préinst que le script exécute avant que le paquet ne soit déballé de son archive Debian (.deb) du fichier.

le script a le code suivant:

#!/bin/bash
set -e
# Automatically added by dh_installinit
if [ "" = 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 installation opération. Si c'est le cas, il vérifie si mon application vient d'être installée sur le système. Si c'est le script affiche le message "MyApplicationName est juste installé" et se termine ( return 1 signifie qui se termine par une "erreur", n'est-ce pas?).

si L'utilisateur demande au système de paquets Debian/Ubuntu d'installer mon paquet, le script supprime aussi deux répertoires.

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

437
demandé sur klay 2013-10-27 23:06:32

4 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 tels que les gens écrivant cette FAQ sur irc freenode #bash), mieux utiliser :

trap 'do_something' ERR

pour exécuter la fonction do_something lorsque des erreurs se produisent.

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

491
répondu Gilles Quenot 2018-07-13 12:39:48

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

61
répondu Robin Green 2013-10-27 19:14:29

comme pour bash - the Set Builtin manuel, si -e / errexit est défini, shell sort immédiatement si un pipeline se compose d'un seul simple commande , une liste ou une commande composée retourne un statut non-zéro.

Par défaut, le statut de sortie d'un pipeline est le statut de sortie de la dernière commande dans le pipeline, à moins que l'option pipefail est activée (elle est désactivée par défaut).

si c'est le cas, l'état de retour de la dernière commande (la plus à droite) pour sortir avec un état non nul, ou zéro si toutes les commandes sortent avec succès.

si vous souhaitez exécuter quelque chose à la sortie, essayez de définir trap , par exemple:

trap onexit EXIT

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

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

il y a une option similaire -E / errtrace qui serait piéger sur ERR à la place, par exemple:

trap onerr ERR

exemples

exemple de statut Zéro:

$ true; echo $?
0

état différent de zéro exemple:

$ false; echo $?
1

en Niant le statut des exemples:

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

avec pipefail étant handicapé:

$ 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

essai avec pipefail activé:

$ bash -c 'set -o pipefail -e; true | false | true; echo success'; echo $?
1
34
répondu kenorb 2017-05-23 11:55:11

j'ai trouvé cette question en Googlant, en essayant de comprendre quel était le statut de sortie pour un script qui a été avorté en raison d'un set -e . La réponse ne semble pas évidente pour moi, d'où cette réponse. Fondamentalement, set -e annule 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 j'ai la coque a script outer-test.sh :

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

le code pour inner-test.sh est:

#!/bin/sh
exit 26;

quand j'exécute outer-script.sh à partir de la ligne de commande, mon script extérieur se termine par le code de sortie du script intérieur:

$ ./outer-test.sh
$ echo $?
26
32
répondu entpnerd 2017-12-13 18:18:48