Wenn ich renne
export TEST=foo
echo $TEST
Es gibt foo aus.
Wenn ich renne
TEST=foo echo $TEST
Es tut nicht. Wie kann ich diese Funktionalität erhalten, ohne Export oder ein Skript zu verwenden?
shell
environment-variables
echo
ashleysmithgpu
quelle
quelle
Antworten:
Dies liegt daran, dass die Shell die Variable in der Befehlszeile erweitert, bevor sie den Befehl ausführt, und die Variable zu diesem Zeitpunkt nicht vorhanden ist. Wenn du benutzt
es wird klappen.
export
wird die Variable in der Umgebung von später ausgeführten Befehlen erscheinen lassen (wie dies in Bash funktioniert, siehehelp export
). Wenn die Variable nur in der Umgebung eines Befehls angezeigt werden soll, verwenden Sie das, was Sie versucht haben:quelle
$TEST
bevor die Befehlszeile ausgeführt wird. Sobald das ausgeführtecho
wird (beachten Sie auch, dass diesecho
normalerweise in den integrierten Shell-Befehl und nicht in übersetzt wird/bin/echo
), wird die in der Umgebung festgelegte Variable angezeigt. Weistecho $TEST
jedoch nichtecho
an, den Inhalt einer VariablenTEST
aus ihrer Umgebung auszugeben . Es weist die Shell an,echo
mit Argument zu arbeiten, das dem entspricht, was sich aktuell in der aufgerufenen Variablen befindetTEST
- und das sind zwei sehr unterschiedliche Dinge.var=value sh -c 'echo "$var"'
?"… $var …"
), aber nicht in einfache Anführungszeichen (zB'… $var …'
) gesetzt. Daecho "$var"
sich der gesamte String in einfachen Anführungszeichen befindet, wird er an die new (sh -c
) - Shell übergeben, ohne von der äußeren, interaktiven Shell interpretiert zu werden. … (Fortsetzung)sh -c
) untergeordneten Shell.Ich vermute, Sie möchten Shell- Variablen haben, um einen begrenzten Bereich zu haben, anstatt Umgebungsvariablen. Umgebungsvariablen sind eine Liste von Zeichenfolgen, die bei ihrer Ausführung an Befehle übergeben werden .
Im
Sie übergeben den
var=value
String an die Umgebung, die das Echo empfängt. Tutecho
jedoch nichts mit seiner Umgebungsliste und wird sowieso in den meisten Shellsecho
eingebaut und daher nicht ausgeführt .Wenn du geschrieben hättest
Das wäre eine andere Sache gewesen. Hier übergeben wir
var=value
densh
Befehl undsh
verwenden zufällig seine Umgebung. Shells konvertieren jede der Variablen, die sie von ihrer Umgebung erhalten, in eine Shell-Variable, sodass dievar
Umgebungsvariable, die siesh
empfängt, in eine$var
Variable konvertiert wird. Wenn sie in dieserecho
Befehlszeile erweitert wird, wird dies zuecho value
. Da die Umgebung standardmäßig vererbt wird,echo
wird sie auchvar=value
in ihrer Umgebung empfangen (oder würde ausgeführt werden),echo
kümmert sich aber auch hier nicht um die Umgebung.Nun, wenn Sie, wie ich vermute, den Umfang der Shell-Variablen einschränken möchten, gibt es mehrere mögliche Ansätze.
Portabel (Bourne und POSIX):
Das obige (...) startet eine Sub-Shell (ein neuer Shell-Prozess in den meisten Shells), daher wirkt sich jede dort deklarierte Variable nur auf diese Sub-Shell aus. Daher würde ich erwarten, dass der obige Code "1: value" ausgibt. und "2:" oder "2: was-war-vorher-gesetzt".
Mit den meisten Bourne-ähnlichen Shells können Sie Funktionen und das "lokale" Builtin verwenden:
Mit zsh können Sie Inline-Funktionen verwenden:
oder:
Mit bash und zsh (aber nicht ash, pdksh oder AT & T ksh) funktioniert dieser Trick auch:
Eine Variante , die in ein paar mehr Granaten (funktioniert
dash
,mksh
,yash
) , aber nichtzsh
(es sei denn , insh
/ksh
Emulation):(Die Verwendung
command
vor einem speziellen (hiereval
) in POSIX-Shells beseitigt deren Besonderheit (hier bleiben die von ihnen zugewiesenen Variablen nach ihrer Rückkehr wirksam).)quelle
Sie tun es richtig, aber die Bash - Syntax ist einfach falsch zu interpretieren: Sie könnten denken , dass
echo $TEST
bewirkt , dassecho
holenTEST
env var es dann drucken, es funktioniert nicht. So gegebendann
beinhaltet die folgende Sequenz:
Die Shell analysiert die gesamte Befehlszeile und führt alle Variablensubstitutionen aus, sodass die Befehlszeile zu wird
Es erstellt die vor dem Befehl festgelegten temporären Variablen, speichert also den aktuellen Wert von
TEST
und überschreibt ihn mit 456; Die Kommandozeile ist jetztEs führt den verbleibenden Befehl aus, der in diesem Fall 123 an stdout ausgibt (der verbleibende Shell-Befehl hat also nicht einmal den Temp-Wert von verwendet
TEST
).Es stellt den Wert von wieder her
TEST
Verwenden Sie stattdessen printenv, da keine Variablensubstitution erforderlich ist:
quelle
printenv
hilfreich für das Testen / Proof of Concept (verhält sich wie ein Skript, im Gegensatz zuecho
)Sie können dies erreichen, indem Sie verwenden:
quelle
TEST=foo
wird als separate Anweisung ausgeführt - es wird nicht nur im Kontext von festgelegtecho
.