Évitez d'exécuter le script si une variable n'est pas définie


18

J'ai un script qui ressemble à ceci:

c=0
for f in */*; do
cp -v "$f" "/myhome/CE$(printf '%0*d' 2 $BATCHNUM)-new-stuctures_extracted/test-$(printf '%0*d' 5 $c)"
c=$((c=c+1))
done

Cependant, l'utilisateur doit fournir un appel variable BATCHNUM et sinon je dois forcer l'arrêt de ce script. Ce serait mieux si je pouvais forcer le script qui appelle ce script à s'arrêter aussi (ou même le script # 1 qui appelle le script # 2 qui appelle ce script).

Réponses:


28

Le moyen le plus rapide est probablement d'ajouter ces deux lignes au début du script:

set -u # or set -o nounset
: "$BATCHNUM"

La première ligne définit l' nounsetoption dans le shell exécutant le script, qui s'interrompt si vous essayez de développer une variable non définie; le second se développe $BATCHNUMdans le contexte d'un no-op, pour déclencher l'abandon avant de faire autre chose.

Si vous voulez un message d'erreur plus utile, vous pouvez plutôt écrire:

if [[ -z "$BATCHNUM" ]]; then
    echo "Must provide BATCHNUM in environment" 1>&2
    exit 1
fi

Ou similaire.


18

Ici, vous voulez vérifier qu'il BATCHNUMest défini et non nul.

Le shell POSIX fournit une extension de paramètre pour ce travail. Il suffit d'ajouter cette ligne avant d'utiliser BATCHNUM:

: "${BATCHNUM:?Variable not set or empty}"

ou mieux pour définir la valeur par défaut BATCHNUMsi l'utilisateur n'en a pas fourni:

: "${BATCHNUM:=3}"

4
[ -n "$BATCHNUM" ] || { kill "$PPID"; exit 1; }
#Unless $BATCHNUM is defined and unempty, ask parent process to exit and exit w/ 1

Cela fonctionnera sur bash et dans un sh POSIX. Je préfère ne pas faire de différence entre les variables vides et les variables non définies (c'est-à-dire que je n'aime pas set -u, mais c'est juste moi).


2

Les lignes

if [ -z "$BATCHNUM" ]; then
    exit 2;
fi

vérifier vide $BATCHNUM. Avec $PPIDvous, vous pouvez faire le mal que vous voulez à vos parents ( kill $PPID). Pour assassiner votre grand-parent, vous devez obtenir l'identifiant du processus par d'autres moyens, comme regarder les données dans /proc/$PPID.

Cependant, si votre parent décède, il vous envoie un signal ( SIGHUP), vous devez donc le piéger avant de commencer à tuer quelqu'un:

trap '' SIGHUP

Mise à jour: Si vous pensez que vous devez tuer vos parents, vous le faites mal. Renvoyez simplement un code de sortie significatif. Le script parent doit vérifier le code retour du script appelé et réagir en conséquence.


1
un peu brutal .... :)
user40780

1

Pour tester si BATCHNUMest défini et quitter s'il ne l'est pas:

if [ -n "${BATCHNUM-a}" ]; then
  echo >&2 "Fatal error: BATCHNUM not set"
  exit 2
fi

Si vous souhaitez également rejeter le cas où BATCHNUMest vide, utilisez ${BATCHNUM:+a}au lieu de ${BATCHNUM+a}. Pour plus d'informations sur la ${VARIABLE+TEXT_IF_NULL}construction d'expansion des paramètres, voir par exemple le manuel bash .

Ne tuez pas le processus parent. Vous ne savez pas quel est le processus parent. Si un script qui appelle celui-ci doit abandonner si ce script échoue, faites-lui vérifier l'état de sortie de ce script. Par exemple, dans le script # 2:

script3 || exit $?

ou utilisez set -epour abandonner le script si une commande renvoie un état d'échec (différent de zéro).

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.