Warum nicht Variablen in dieselbe Zeile exportieren, die Sie ihnen zuweisen?

44

From Was ist das letzte Argument des vorherigen Befehls?

Shellcheck weist Sie an, keine Variablen in dieselbe Zeile zu exportieren, die Sie ihnen zuweisen.

Ich habe mich gefragt, warum?

Hat der gleiche Rat gilt alias, declare, export, local, readonly, und typeset?

Tim
quelle
9
Die fragliche Shellcheck-Regel ist SC2155. Es gibt eine ziemlich gute Dokumentation im Shellcheck- Wiki .
Phunehehe
3
Auch einige ältere Muscheln würden eine exportgemeinsame Aufgabe nicht annehmen . Die Heirloom Bourne Shell gibt beispielsweise den Fehler "foo = 2 ist kein Bezeichner" aus.
Dennis Williamson

Antworten:

54

Das Problem ist, dass in Bash jeder Befehl nur einen Exit-Code hat. Bei Ihnen wird export foo="$(false)"der Exit-Code von falseeinfach verworfen. Wenn du es stattdessen tust

foo="$(false)"
export foo

Auf den fehlgeschlagenen ersten Befehl kann beispielsweise durch die errexitEinstellung reagiert werden.

Das Deklarieren und Zuweisen eines String-Literales wie dieses export foo='bar'leidet natürlich nicht an diesem Problem. Aber Veränderung ist die einzige Konstante in der Softwareentwicklung, und es ist einfach eine gute Sache, solche Aussagen zukunftssicher zu machen, indem man sie aufteilt.

Zusätzlich zu den von Ihnen erwähnten zuweisungsspezifischen Befehlen gibt es auch mehrere Befehle in einer einzelnen Zuweisung, wie z foo="$(false)$(true)". Siehe pipefailin man bashfür einen weiteren solchen Falle.

Eine andere Sache, an die man sich erinnern sollte, ist, dass die Reihenfolge der Deklaration und Zuordnung manchmal relevant ist. Beispielsweise möchten Sie Variablen deklarieren, bevor Sie sie zuweisen. (Leider ist es nicht möglich, Variablen zu deklarieren, bevor Sie sie zum ersten Mal zuweisen.)local readonly

l0b0
quelle
Wenn man also eine Variable aus einem Literal setzt und keinen zu verwerfenden Exit-Code hat, ist nichts falsch daran, alles in einer Zeile zu machen.
Monty Harder
1
Was diesen Shellcheck-Fehler betrifft, nein. Da die jetzt gelöschten Antworten jedoch nur zur Hälfte übereinstimmten, unterstützte die Bourne-Shell die Zuweisungssyntax exportfür nicht. Einige Jahre lang gab es die Weisheit, dies zu tun, wenn der Interpreter wahrscheinlich die Bourne-Shell sein sollte.
JdeBP
@JdeBP, beachten Sie, dass die Bourne-Shell diese Funktion unterstützt hat foo=$(cmd) export foo, jedoch mit demselben Vorbehalt, mit dem der Beendigungsstatus cmdverloren gegangen ist (jedoch wurde die Shell beendet, wenn ein Fehler auftrat set -e).
Stéphane Chazelas
Das wurde von meinem ersten Satz abgedeckt.
JdeBP