TL; DR: Im Fall von export FOO=bar
ruft bash seine temporäre Umgebungserstellung auf, setzt FOO=bar
in dieser Umgebung und gibt dann einen endgültigen Befehl von aus export FOO
. An dieser Stelle FOO
wird als letztes Argument genommen.
Ah, der viel missbrauchte $_
:
($ _, ein Unterstrich.) Legen Sie beim Shell-Start den absoluten Pfadnamen fest, der zum Aufrufen der Shell oder des Shell-Skripts verwendet wird, die ausgeführt werden, wie in der Umgebungs- oder Argumentliste übergeben. Erweitert anschließend nach der Erweiterung zum letzten Argument des vorherigen Befehls. Stellen Sie auch den vollständigen Pfadnamen ein, der zum Aufrufen jedes ausgeführten und in die in diesen Befehl exportierte Umgebung platzierten Befehls verwendet wird. Beim Überprüfen von E-Mails enthält dieser Parameter den Namen der E-Mail-Datei.
Schauen wir uns einige Variationen an:
$ man; echo $_
What manual page do you want?
man
$ man foo; echo $_
No manual entry for foo
foo
$ echo; echo $_
echo
$ echo bar foo; echo $_
bar foo
foo
$ foo=x eval 'echo $foo'; echo $_
x
echo $foo
$ bar() { man $1; }; echo $_
foo
$ for (( i=0; $i<0; i=i+1 )); do echo $i; done; echo $_
foo
$ bar; echo $_
What manual page do you want?
man
$ bar foo; echo $_
No manual entry for foo
foo
$ MANPATH=/tmp; echo $_
$ export MANPATH=/tmp; echo $_
MANPATH
Wir sehen hier also drei Muster:
- Vom Dateisystem aufgerufene Befehle, Funktionen und integrierte Funktionen verhalten sich wie allgemein erwartet:
$_
Wird auf den Befehlsnamen selbst gesetzt, wenn keine Argumente vorhanden sind, andernfalls das letzte der dargestellten Argumente.
- Nach Funktionsdefinitionen, Schleifen und anderen logischen Konstruktionen:
$_
wird nicht geändert.
- Alles andere:
$_
ist auf etwas eingestellt, was nicht ganz erwartet wird; seltsam.
Ich habe den Code instrumentiert, um einen Einblick in die Verrücktheit zu geben.
$ ./bash --noprofile --norc -c 'man foo'
lastword=[man]
lastarg=[foo]
$ ./bash --noprofile --norc -c 'export FOO=bar'
lastword=[export]
lastarg=[FOO=bar]
bind_variable, name=[FOO], value=[bar]
before bind_lastarg, lastarg=[FOO]
bind_lastarg, arg=[FOO]
bind_variable, name=[_], value=[FOO]
$ ./bash --noprofile --norc -c 'declare FOO=bar'
lastword=[declare]
lastarg=[FOO=bar]
bind_variable, name=[FOO], value=[(null)]
before bind_lastarg, lastarg=[FOO=bar]
bind_lastarg, arg=[FOO=bar]
bind_variable, name=[_], value=[FOO=bar]
Sie können sehen, dass der Parserlastarg=
in allen Fällen das erwartete letzte Argument ( ) sieht , aber was danach passiert, hängt davon ab, was Bash für richtig hält. Siehe execute_cmd.c, execute_simple_command () .
Im Fall von export FOO=bar
nimmt bash die Zuweisung vor und exportiert dann die Variable. Dies scheint im Einklang mit der Behauptung der Dokumentation zu stehen, dass das letzte Argument nach der Erweiterung berechnet wurde.
EDITOR
ist ein Argument zum Exportieren