TL; DR: W przypadku export FOO=barbash wywołuje tymczasowe tworzenie środowiska, ustawia się FOO=barw tym środowisku, a następnie wydaje polecenie końcowe export FOO. W tym momencie FOOjest uważany za ostatni argument.
Ach, nadużywane $_:
($ _, znak podkreślenia.) Przy uruchamianiu powłoki ustaw bezwzględną nazwę ścieżki używaną do wywoływania powłoki lub skryptu powłoki wykonywanej tak, jak przekazano w środowisku lub liście argumentów. Następnie rozwija się do ostatniego argumentu do poprzedniego polecenia, po rozwinięciu. Ustawiono również na pełną ścieżkę używaną do wywoływania każdego wykonanego polecenia i umieszczanego w środowisku eksportowanym do tego polecenia. Podczas sprawdzania poczty ten parametr przechowuje nazwę pliku poczty.
Spójrzmy na kilka odmian:
$ 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
Widzimy tutaj trzy wzory:
- Polecenia wywoływane z systemu plików, funkcji i wbudowanych funkcji działają zgodnie z ogólnymi oczekiwaniami:
$_w przypadku braku argumentów ustawiana jest sama nazwa polecenia, w przeciwnym razie ostatni z przedstawionych argumentów.
- Po definicjach funkcji, pętlach i innych konstrukcjach logicznych:
$_nie jest modyfikowany.
- Wszystko inne:
$_jest ustawione na coś, czego nie do końca się spodziewam; dziwne.
Oprzyrządowałem kod, aby zapewnić wgląd w dziwność.
$ ./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]
Możesz zobaczyć, że parser widzi oczekiwany ostatni argument ( lastarg=) we wszystkich przypadkach, ale to, co stanie się później, zależy od tego, co według bash powinno się wydarzyć. Zobacz execute_cmd.c, execute_simple_command () .
W przypadku export FOO=barbash dokonuje przypisania, a następnie eksportuje zmienną. Wydaje się to spójne z twierdzeniem dokumentacji, że ostatni argument został obliczony po rozwinięciu.
EDITORjest argumentem do eksportu