Wo ist "export var = value" nicht verfügbar?

31

Ich habe - wahrscheinlich im Usenet Mitte der neunziger Jahre (!) - das Konstrukt aufgegriffen

export var=value

ist ein Bashismus, und das ist der tragbare Ausdruck

var=value
export var

Ich befürworte dies seit Jahren, aber kürzlich hat mich jemand dazu herausgefordert, und ich kann wirklich keine Dokumentation finden, die meine früheren festen Überzeugungen bestätigt.

Googeln für "export: command not found" scheint keine Fälle , in denen tatsächlich jemand dieses Problem hatte. Selbst wenn es echt ist, ist es nicht sehr häufig.

(Die Treffer, die ich bekomme, scheinen Neulinge zu sein, die Interpunktion kopieren / einfügen und am Ende mit 'export: command not foundoder einigen solchen gelandet sind oder versuchen, exportmit zu verwenden sudo; und Neulingcsh versuchen, die Bourne-Shell-Syntax zu verwenden.)

Ich kann mit Sicherheit sagen, dass es unter OS X und unter verschiedenen Linux-Distributionen funktioniert, einschließlich derjenigen, in denen es sich shbefindet dash.

sh$ export var=value
sh$ echo "$var"
value
sh$ sh -c 'echo "$var"'  # see that it really is exported
value

In der heutigen Welt kann man das mit Sicherheit sagen export var=value es sicher ist, es zu benutzen?

Ich würde gerne verstehen, was die Konsequenzen sind. Wenn es nicht portabel zu Version 7 "Bourne classic" ist, ist das kaum mehr als eine Kleinigkeit. Wenn es Produktionssysteme gibt, in denen die Shell mit dieser Syntax wirklich nicht zurechtkommt, wäre es hilfreich, dies zu wissen.

Tripleee
quelle
2
danke endlich habe ich verstanden, warum ich so oft das sehe, was ich für nutzlos hielt: var = value; export var
Thorsten Staerk
2
Es gibt immer noch ein paar Solaris-Boxen, die in ihren Standardwerkzeugen notorisch sparsam sind. am anderen Ende des Spektrums, kommt nicht busyboxmit einer eigenen minimalen Schale? (Ich bin nicht in der Lage, es in dieser Sekunde richtig zu versuchen.)
Ulrich Schwarz
Danke Ulrich, vielleicht ist Solaris der Schuldige, warum es diese lange Syntax immer noch gibt.
Thorsten Staerk

Antworten:

20
export foo=bar

wurde von der Bourne-Shell nicht unterstützt (eine alte Shell aus den 70er Jahren, von der moderne shImplementierungen wie ash / bash / ksh / yash / zsh abgeleitet sind). Das wurde eingeführt von ksh.

In der Bourne-Shell würden Sie Folgendes tun:

foo=bar export foo

oder:

foo=bar; export foo

oder mit set -k:

export foo foo=bar

Nun, das Verhalten von:

export foo=bar

variiert von Schale zu Schale.

Das Problem ist, dass Zuweisungen und einfache Befehlsargumente unterschiedlich analysiert und interpretiert werden.

Das foo=barObige wird von einigen Shells als Befehlsargument und von anderen als Aufgabe (manchmal) interpretiert.

Zum Beispiel,

a='b c'
export d=$a

wird interpretiert als:

'export' 'd=b' 'c'

mit einigen Shells ( ash, älteren Versionen von zsh(in der Sh-Emulation) yash) und:

'export' 'd=b c'

in den anderen ( bash, ksh).

Während

export \d=$a

oder

var=d
export $var=$a

würde in allen Schalen gleich interpretiert werden (als 'export' 'd=b' 'c' ) da dieser Backslash oder das Dollarzeichen die Shells stoppt, die ihn unterstützen, um diese Argumente als Zuweisungen zu betrachten.

Wenn er exportselbst angegeben wird oder das Ergebnis einer gewissen Ausdehnung ist (auch teilweise), würde er, abhängig von der Schale, auch die Sonderbehandlung einstellen.

Weitere Informationen hierzu finden Sie unter " Werden für die Zuweisung lokaler Variablen Anführungszeichen benötigt? ".

Die Bourne-Syntax:

d=$a; export d

wird von allen Shells ohne Mehrdeutigkeit gleich interpretiert ( d=$a export dfunktioniert auch in der Bourne - Shell und in POSIX - kompatiblen Shells, jedoch nicht in neueren Versionen von, zshsofern nicht insh Emulation).

Es kann noch viel schlimmer werden. Siehe zum Beispiel die jüngste Diskussion überbash wann Arrays betroffen sind.

(IMO, es war ein Fehler, diese Funktion einzuführen ).

Stéphane Chazelas
quelle
Ich war überrascht, dass das Semikolon nicht benötigt wird foo=bar export foo, da ich es immer dort gesehen hatte. Ich weiß, dass Export eine eingebaute Funktion ist, aber warum verhält es foo=bar; foo=baz export foo; echo $foosich anders als foo=bar; foo=baz /bin/cat /dev/null; echo $foo?
jrw32982 unterstützt Monica
3
@ jrw32982, weil es eine eingebaute ist. Das bekommt man in modernen POSIX-Shells aber nur für spezielle Builtins was export.
Stéphane Chazelas
Obwohl es diskutiert declare, nicht export, empfehle ich , dass jeder, die Sorgen um die Sicherheit , die Diskussion zu lesen Link , dass StéphaneChazelas zu bash.bugs vorgesehen .
John1024
Gute Antwort! Aber es hat lange gedauert, bis d=$a export des von allen Shells ohne Mehrdeutigkeit gleich interpretiert wird ;-)
conny
@conny, d=$a export dfunktioniert in nicht mehr zsh, daher habe ich die Antwort aktualisiert. Siehe Bearbeiten.
Stéphane Chazelas
28

Es ist kein Bashismus, sondern eine POSIX-konforme Syntax. Es begann eigentlich vor langer Zeit als Kshism und wurde später von fast allen Bourne-basierten Syntax-Shells übernommen. Die einzige berüchtigte Ausnahme ist /bin/shSolaris 10 und älter, das an der Bourne-Shell-Syntax festhält. Hoffentlich verwendet Solaris 11 eine POSIX-kompatible Shell als /bin/sh.

Übrigens exportwar bereits ein Befehl in die Bourne-Shell integriert, weshalb das Suchen nach export: command not foundirreführend war.

Hier ist das Verhalten der Bourne-Shell in exportVerbindung mit einer Beeinträchtigung:

$ export var=22
var=22: is not an identifier

Für die Nostalgiker die Quellcode dieser ursprünglichen Bourne-Shell verfügbar und kann für die meisten Unix- und Linux-Distributionen kompiliert werden.

jlliagre
quelle
Vielen Dank für den historischen Einblick und die richtige Fehlermeldung, die Sie bei Google erhalten haben! Rückblickend ist
klar
4
Dies ist nicht der Quellcode der ursprünglichen Bourne-Shell, sondern eine modifizierte OpenSolaris-Shell. Es ist die Bourne-Muschel, aber nachdem sie jahrzehntelang weiterentwickelt wurde. Die Original-Bourne-Shell, die mit Unix V7 ausgeliefert wurde, ist bei der Unix Heritage Society
Stéphane Chazelas,
1
@Stéphanechazelas Genau genommen hast du wie immer recht. Beachten Sie jedoch, dass ich nicht "die ursprüngliche Bourne-Shell", sondern "diese ursprüngliche Bourne-Shell" geschrieben habe, da ich mich auf die von Solaris 10 verwendete Shell und deren Quellcode bezog, die auf modernen Plattformen kompiliert werden können. Beachten Sie auch, dass die Bourne-Shell zwischen 1977 und 1989 mehrere Funktionen hinzugefügt hat, aber in den letzten 25 Jahren im Wesentlichen nicht mehr weiterentwickelt wurde (externe Portierung / Anpassung an neuere Plattformen und Fehlerkorrekturen).
Juli,