lutilisation de set -u ne fonctionne pas comme prévu

Japprends à utiliser efficacement différentes options set dans mon script et suis tombé sur set -u qui semble être parfait pour quitter mon script si une variable nest pas définie correctement (ex. suppression dutilisateurs). Selon la page man , set -u et set -e fait ce qui suit …

-e Exit immediately if a command exits with a non-zero status. -u Treat unset variables as an error when substituting. 

Jai créé un script de test pour tester cette fonctionnalité, mais il ne semble pas fonctionner comme prévu . Peut-être que quelquun pourrait mieux mexpliquer mon problème et ce que jinterprète mal? Le script de test est ci-dessous. Merci.

set -e set -u testing="This works" echo $? echo ${testing} testing2= echo $? echo ${testing2} testing3="This should not appear" echo $? echo ${testing3} 

Je mattends à ce que le script affiche 0 et « Cela fonctionne » , puis échoue car ${testing2} est non défini.

À la place, je suis affiché 0 et « Cela fonctionne » , suivi de 0 puis 0 Cela ne devrait pas apparaître

Quelquun peut-il fournir des connaissances? Merci.

Commentaires

  • Alors suivez… y a-t-il un moyen de rendre illégale la définition dune variable sur la chaîne nulle / de générer une erreur? Je ' ne devine pas.

Réponse

De  » man Bash « :

Un paramètre est défini si une valeur lui a été attribuée. La chaîne nulle est une valeur valide. Une fois quune variable est définie, elle ne peut être annulée quen utilisant la commande intégrée unset.

Lorsque vous faites testing2= vous définissez la variable sur la chaîne nulle.

Remplacez-la par unset testing2 et réessayez.


Le set -e naide pas dans ce cas car une affectation na jamais un code de sortie de 1. Essayez ceci pour voir que la dernière commande exécutée (laffectation) a un code de sortie de 0, ou lire cette question :

$ false; a=""; echo $? 0 

Et je crois aussi que lutilisation de set -e est plus un problème quune solution.

Ce qui peut provoquer une erreur avec lutilisation de variables non définies est set -u:

#!/bin/bash set -u testing="This works" echo ${testing} unset testing2 echo ${testing2} testing3="This should not appear" echo ${testing3} 

Affiche:

$ ./script.sh This works ./script.sh: line 9: testing2: unbound variable 

Réponse

testing2= définit la variable testing2 sur une chaîne vide; la variable est en fait définie .

Cependant, si vous exécutez echo $testing99 dans un shell Bash interactif (sans définir errexit, cest-à-dire set -e), vous obtiendrez une erreur:

bash: testing99: unbound variable 

À part

En testant des scripts tout à lheure, jai découvert quun shell interactif ne quittait pas toujours lors dune tentative de développement dune variable qui na pas été définie alors quun shell non interactif (exécutant un script shell) quitte toujours . Selon la page de manuel POSIX pour set:

-u Le shell doit écrire un message derreur standard lorsquil essaie de développer une variable qui nest pas définie et de quitter immédiatement. Un shell interactif ne se fermera pas.

Un shell interactif Bash ne se fermera que si errexit a également défini. Dun autre côté, un shell de tableau de bord interactif ne se fermera pas – même si set -e a déjà été exécuté.

Commentaires

  • Si le tiret ne se termine pas avec set -e; set -u; unset aa; echo $ aa, alors dash est faux.
  • @schily Quand jai remarqué cela pour la première fois, je me suis dit que les auteurs du dash savaient mieux que moi et quil y avait peut-être une ambiguïté dans les spécifications POSIX mais vérifié pubs.opengroup.org/onlinepubs/9699919799/utilities/… , je suis daccord que cela ressemble à un bug, daccord.
  • Il y a une règle simple: lorsque Korn Shell et Bourne Shell sont daccord et quune autre implémentation de shell a un écart, alors lautre shell se comporte de manière incorrecte.

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *