Cette question est apparue dans un quiz de pré-entretien et ça me rend fou. Quelqu'un peut-il répondre à cela et me mettre à l'aise? Le quiz ne fait pas référence à un shell en particulier, mais la description du poste concerne un système d'exploitation unix. encore une fois la question est simplement ...
Que fait 'set-e', et pourquoi pourrait-il être considéré comme dangereux?
Réponses:
set -e
provoque la fermeture du shell si une sous-commande ou un pipeline renvoie un statut différent de zéro.La réponse que l'intervieweur recherchait probablement est la suivante:
De http://www.debian.org/doc/debian-policy/ch-opersys.html 9.3.2 -
Cette question est valable du point de vue de l'interviewer, car elle évalue la connaissance pratique du candidat en script et en automatisation au niveau du serveur.
la source
De
bash(1)
:Malheureusement, je ne suis pas assez créatif pour imaginer pourquoi cela serait dangereux, si ce n’est "le reste du script ne sera pas exécuté" ou "cela masquera peut-être de vrais problèmes".
la source
set
! Je finis toujours àbuiltin(1)
. Merci.set
doit être trouvéeman 1 bash
?? et comment quelqu'un pourrait-il trouver l'-e
option pour leset
mot clé dans une page de manuel extrêmement volumineuse? vous ne pouvez pas simplement/-e
chercher icihelp set
Il convient de noter qu’il
set -e
est possible d’activer et de désactiver différentes sections d’un script. Il n'est pas nécessaire qu'il soit activé pour l'exécution du script entier. Il pourrait même être activé de manière conditionnelle. Cela dit, je ne l'utilise jamais puisque je gère (ou non) ma propre erreur.Il convient également de noter que cela provient de la section de la page de manuel Bash sur la
trap
commande, qui décrit également leset -e
fonctionnement de certaines conditions.Il existe donc certaines conditions dans lesquelles un statut différent de zéro ne provoquera pas de sortie.
Je pense que le danger est de ne pas comprendre quand
set -e
entrer en jeu et quand il ne comprend pas et de s’y fier à tort en supposant une hypothèse invalide.Veuillez également vous reporter à BashFAQ / 105 Pourquoi set -e (ou set -o errexit, ou piège ERR) ne répond-il pas à mes attentes?
la source
N'oubliez pas qu'il s'agit d'un questionnaire pour un entretien d'embauche. Les questions ont peut-être été écrites par le personnel actuel et elles peuvent être fausses. Ce n’est pas forcément mauvais et tout le monde fait des erreurs, et les questions posées lors des entretiens restent souvent sans réponse dans un coin sombre, et ne se posent qu’au cours d’une interview.
Il est tout à fait possible que "set -e" ne fasse rien que nous considérions comme "dangereux". Mais l’auteur de cette question peut croire à tort que «set-e» est dangereux, en raison de leur ignorance ou de leur parti pris. Peut-être qu'ils ont écrit un script shell buggy, le bombardement a été horrible, et ils ont pensé à tort que «set-e» était à blâmer, alors qu'en fait ils ont négligé d'écrire la vérification d'erreur correcte.
J'ai participé à probablement 40 entretiens d'embauche au cours des 2 dernières années, et les intervieweurs posent parfois des questions incorrectes ou des réponses erronées.
Ou peut-être que c'est une question piège, qui serait boiteuse, mais pas totalement inattendue.
Ou peut-être est-ce une bonne explication: http://www.mail-archive.com/[email protected]/msg473314.html
la source
set -e
indique à bash, dans un script, de quitter chaque fois que quelque chose retourne une valeur de retour non nulle.Je pouvais voir à quel point cela pouvait être ennuyeux, et buggué, pas sûr de dangereux, à moins que vous n'ayez ouvert des autorisations sur quelque chose, et avant de pouvoir les restreindre à nouveau, votre script est mort.
la source
set -e
, en fait, il parle de paresse d'ignorer les erreurs de vérification dans vos scripts ... alors gardez cela à l'esprit, avec cet employeur aussi ... s'ils l'utilisent beaucoup, à quoi ressemblent leurs scripts, qu'il vous faudra inévitablement maintenir ...set -e
termine le script si un code de sortie différent de zéro est rencontré, sauf dans certaines conditions. Pour résumer les dangers de son utilisation en quelques mots: il ne se comporte pas comme les gens le pensent.À mon avis, il devrait être considéré comme un piratage dangereux qui continue d'exister uniquement à des fins de compatibilité. L'
set -e
instruction ne transforme pas le shell d'un langage qui utilise des codes d'erreur en un langage qui utilise un flux de contrôle semblable à une exception, il tente simplement de peu émuler ce comportement.Greg Wooledge a beaucoup à dire sur les dangers de
set -e
:set -e
)Dans le deuxième lien, vous trouverez divers exemples de comportement non intuitif et imprévisible de
set -e
.Quelques exemples de comportement non intuitif de
set -e
(certains tirés du lien wiki ci-dessus):let x++
renvoie 0, qui est traité par lelet
mot clé comme une valeur faussement et transformé en un code de sortie non nul.set -e
le remarque et termine silencieusement le script.Ce qui précède fonctionne comme prévu, en affichant un avertissement s’il
/opt/foo
existe déjà.Ce qui précède, bien que la seule différence réside dans le fait qu’une seule ligne a été refactorisée dans une fonction, se terminera s’il
/opt/foo
n’existe pas. En effet, le fait qu’il ait fonctionné à l’origine constitue une exception spéciale auset -e
comportement de. Lorsquea && b
renvoie non nul, il est ignoré parset -e
. Cependant, maintenant que c'est une fonction, le code de sortie de la fonction est égal au code de sortie de cette commande, et la fonction renvoyant une valeur autre que zéro mettra fin au script de manière silencieuse.Ce qui précède lira le tableau à
config_vars
partir du fichierconfig
. Comme l’intéressé le souhaite, il se termine par une erreur s’ilconfig
manque. Comme l’auteur n’a peut-être pas l’intention de le faire, il se termine en silence siconfig
ne se termine pas par une nouvelle ligne. Siset -e
n'étaient pas utilisés ici,config_vars
ils contiendraient toutes les lignes du fichier, qu'il se termine ou non par une nouvelle ligne.Utilisateurs de Sublime Text (et d'autres éditeurs de texte gérant mal les nouvelles lignes), méfiez-vous.
L’auteur peut raisonnablement s’attendre à ce que si, pour une raison quelconque, l’utilisateur
$user
n’existe pas, lagroups
commande échoue et le script se termine au lieu de laisser l’utilisateur effectuer une tâche non auditée. Cependant, dans ce cas, laset -e
résiliation ne prend jamais effet. Si,$user
pour une raison quelconque, ne peut pas être trouvé, au lieu de mettre fin au script, lashould_audit_user
fonction ne fera que renvoyer des données incorrectes comme si ellesset -e
n'étaient pas en vigueur.Cela s'applique à toute fonction invoquée à partir de la partie condition d'une
if
instruction, peu importe la profondeur d'imbrication, peu importe où elle est définie, peu importe si vousset -e
y retournez. Utiliserif
à tout moment désactive complètement l'effet deset -e
jusqu'à ce que le bloc de condition soit complètement exécuté. Si l'auteur n'est pas conscient de ce piège ou ne connaît pas l'intégralité de sa pile d'appels dans toutes les situations possibles dans lesquelles une fonction peut être appelée, il écrira un code erroné et le faux sentiment de sécurité fourni parset -e
sera au moins partiellement faire des reproches.Même si l'auteur est pleinement conscient de ce piège, la solution consiste à écrire du code de la même manière que si on l'écrivait sans
set -e
, rendant effectivement ce changement moins inutile. non seulement l'auteur doit écrire le code de traitement d'erreur manuel comme s'ilset -e
n'était pas en vigueur, mais la présence deset -e
peut aussi les avoir dupés en leur faisant croire qu'ils n'étaient pas obligés.Quelques autres inconvénients de
set -e
:let x++
ci-dessus, ce n'est pas le cas. Si le script meurt de manière inattendue, il s’agit généralement de manière silencieuse, ce qui empêche le débogage. Si le script ne meurt pas et que vous vous attendiez à le voir (voir le point précédent), vous avez alors un bug plus subtil et insidieux.if
point -condition.set -e
qu’il a été modifié entre ces versions.set -e
est une question litigieuse, et certaines personnes au courant des problèmes qui l’entourent la recommandent, alors que d’autres recommandent simplement de faire attention pendant qu’il est actif de connaître les pièges. Il existe de nombreux débutantsset -e
dans les scripts qui recommandent tous les scripts comme une solution miracle aux conditions d'erreur, mais dans la réalité, cela ne fonctionne pas ainsi.set -e
n'est pas un substitut à l'éducation.la source
Je dirais que c'est dangereux parce que vous ne contrôlez plus le déroulement de votre script. Le script peut se terminer tant que l'une des commandes qu'il invoque renvoie une valeur autre que zéro. Donc, tout ce que vous avez à faire est de faire quelque chose qui modifie le comportement ou la sortie de l'un des composants, et vous devez terminer le script principal. Ce pourrait être plus un problème de style, mais cela a certainement des conséquences. Que se passe-t-il si votre script principal est supposé définir un drapeau, mais il ne l’a pas fait parce qu’il s’est terminé tôt? Si vous supposez que l'indicateur doit être présent, ou si vous utilisez une valeur par défaut ou une ancienne valeur inattendue, vous finirez par rendre le système défaillant.
la source
Comme exemple plus concret de la réponse de @ Marcin qui m’a personnellement mordue, imaginez qu’il y ait une
rm foo/bar.txt
ligne quelque part dans votre script. Habituellement pas grave sifoo/bar.txt
n'existe pas réellement. Cependant, avecset -e
présent, votre script se terminera tôt! Oops.la source