Pourquoi ne pas exporter des variables sur la même ligne que vous leur affectez?

44

De Quel est le dernier argument de la commande précédente?

shellcheck vous dit de ne pas exporter les variables sur la même ligne que vous les affectez.

Je me demandais pourquoi?

Est -ce que les mêmes conseils à appliquer alias, declare, export, local, readonlyet typeset?

Tim
la source
9
La règle de contrôle de shell en question est SC2155. Il existe une très bonne documentation sur le wiki shellcheck .
Phunehehe
3
De plus, certains coquillages plus âgés n'accepteraient pas une exportcession ensemble. L' héritage Bourne Shell , par exemple, fournit en sortie un « foo = 2 ne soit pas un identificateur » erreur.
pause jusqu'à nouvel ordre.

Réponses:

54

Le problème est que dans Bash, chaque commande n'a qu'un code de sortie. Lorsque vous export foo="$(false)"le code de sortie de falseest simplement supprimé. Si vous faites plutôt

foo="$(false)"
export foo

la première commande défaillante peut être activée, par exemple par le errexitréglage.

Déclarer et affecter un littéral tel que, export foo='bar'bien sûr, ne souffre pas de ce problème. Mais le changement est la seule constante dans le développement de logiciels, et il est simplement bon de le garder pour assurer la pérennité de telles déclarations en les séparant.

Outre les commandes spécifiques aux affectations que vous mentionnez, il existe également plusieurs commandes dans une même affectation, telles que foo="$(false)$(true)". Voir pipefaildans man bashpour un autre tel piège.

Une autre chose à retenir est que la séquence de déclaration et d'assignation est parfois pertinente. Par exemple, vous voudrez déclarer des variables avant de les affecter. (Malheureusement, il n'est pas possible de déclarer des variables avant de les affecter pour la première fois.)local readonly

l0b0
la source
Donc, si vous définissez une variable à partir d'un littéral et qu'il n'y a pas de code de sortie à supprimer, il n'y a rien de mal à tout faire sur une seule ligne.
Monty Harder
1
En ce qui concerne cette erreur de vérification, non. Mais comme les réponses maintenant supprimées étaient à moitié exactes, le shell Bourne ne prenait pas en charge la syntaxe d'affectation export. Par conséquent, pendant plusieurs années, il a été jugé utile de le faire si son interprète était probablement le shell Bourne.
JdeBP
@JdeBP, notez que le shell Bourne a bien pris en charge foo=$(cmd) export foo, mais avec la même réserve que cmdl'état de sortie est perdu (mais a entraîné la sortie du shell en cas d'échec set -e).
Stéphane Chazelas
Cela était couvert par ma première phrase.
JdeBP