Jakie jest znaczenie „_ =”?

29

Po uruchomieniu set -a var=99mogę znaleźć zdanie w wynikach set:

...
TERM=xterm
UID=0
USER=root
VIRTUAL_ENV_DISABLE_PROMPT=1
_=var=99
colors=/etc/DIR_COLORS
...

Czy ktoś mógłby mi powiedzieć, co oznacza „_ =”?

Zauważam, że echo $varnic nie da. Jeśli uruchomię set -a, setto zmienna nie będzie zawierać tej zmiennej. Co się dzieje?

yode
źródło

Odpowiedzi:

16

Kiedy wykonujesz set -a var=99, zdarzają się trzy różne rzeczy (związane z twoim pytaniem):

  1. Ustaw opcję ( -a) (odwróć wykonując set +a), aby wyeksportować zmienne.
  2. Parametry pozycji są „ustawiane” zgodnie z opcjami ( $1ustawione na var=99).
  3. Podkreślenie zmiennej powłoki $_jest ustawiane na ostatni parametr (rozwinięty).

zestaw -a

Wykonanie set -aoznacza wszystkie wyeksportowane zmienne (nowe lub zmienione) (we wszystkich powłokach, z wyjątkiem cshniektórych powłok pokrewnych).

$ set -a
$ myvariable=wer
$ env | grep myvariable
myvariable=wer

Aby odzyskać z tego ustawienia, wystarczy zmienić -Do +:

$ set +a
$ unset myvariable              # to erase it from the environment if it
                                # was exported before the change of set +a
$ myvariable=456544654          # A new value of the variable.
$ env | grep "variable"         # No output means the var does not exist
                                # in the current environment

ustaw var = 99

Tak naprawdę powinno być, set -- var=99aby uniknąć interpretacji opcji (a zestaw ma dużo) z wartościami rozpoczynającymi się od myślnika ( -).

Ustawia listę argumentów (listę parametrów pozycyjnych) na tę po --. Jest to ważne we wszystkich rozsądnych powłokach (nie w csh i in.). Argumenty pozycyjne są drukowane z „$ @” (lub podobnym „$ *”, nie równym).

$ set -- a=1 b=2 c=3
$ echo "$@"
a=1 b=2 c=3

_ = ostatni_argument

A wartość wewnętrznej zmiennej powłoki _zmienia się na ostatni argument wykonywanego wiersza. To jest nie prawda, w prawie wszystkich muszli (JSH, jesion, Yash, myślnik, lksh, mksh, ksh93, attsh i csh tcsh) oraz oczywiście z wyjątkiem bash.

$ echo one two last argument
one two last argument

$ echo "$_"
argument

$ echo This is a new: last_argument
This is a new: last_argument

$ echo "$_"
last_argument

Należy pamiętać, że wartość w $_to wartość po rozwinięciu:

$ a="A New_Argument"
$ echo Something else to test: "$a"
Something else to test: A New_Argument

$ echo "$_"
A New_Argument

Dlatego po wykonaniu:

$ set -a myvar=99; set | grep 'myvar'
_=myvar=99

Otrzymasz opis zmiennej powłoki „$ _”. Działa to również:

$  set -a myvar=99; declare -p _
declare -- _="myvar=99"
Strzałka
źródło
37

Podkreślenie jest w rzeczywistości specjalną zmienną powłoki. To, co widzisz tutaj, to _zmienna podkreślenia ( ) o wartości var=99. Jest tylko do odczytu i jest utrzymywany przez powłokę. To jest:

  • Ustawiany przy uruchamianiu powłoki, zawierający bezwzględną nazwę pliku powłoki lub wykonywanego skryptu, przekazany na liście argumentów.
  • Następnie rozwija się do ostatniego argumentu do poprzedniego polecenia, po rozwinięciu.
  • Podczas sprawdzania poczty ten parametr przechowuje nazwę pliku poczty.
  • Jest również ustawiony na pełną ścieżkę do każdego wykonanego polecenia i umieszczony w środowisku eksportowanym do tego polecenia.

Twój przykład należy do drugiej kategorii. Wpisałeś:

set -a var=99  

Więc ostatni argument nie było var=99, i że była wartość zostałeś ustawienie (nie zostały ustalone vardo 99). Dlatego _zostało to ustawione. I to jest zgłaszane:

_=var=99  

Jest to trochę mylące, ale pierwszy =wskazuje przypisanie do zmiennej _, a drugi jest częścią wartości.

Warto również wspomnieć, że -aopcja setspowoduje, że wszystkie później zdefiniowane zmienne zostaną wyeksportowane.

Bob Eager
źródło
16

Prawidłowa odpowiedź zależy od używanej powłoki:

  • ponieważ bash, cokolwiek @BobEager powiedział, ma zastosowanie
  • o zsh, to jest ustawiony tylko na ostatni argument poprzedniego polecenia, a do pełnej ścieżki polecenia w środowisku komendy za
  • niektóre powłoki dashustawiają tę zmienną tylko podczas uruchamiania sesji interaktywnej

Mogą istnieć także inne cechy szczególne innych powłok. Jako taki nie$_ jest zdefiniowany w POSIX, dlatego należy pamiętać o potencjalnych problemach z przenośnością podczas jego używania.

Uwaga dodatkowa: jeśli Twoim celem jest przypisanie wartości 99 vari udostępnienie jej w środowisku kolejnych podprocesów, poprawna składnia, aby to osiągnąć, to:

export var=99
Dmitrij Grigoriew
źródło
2
Poprawna jest również składnia unset var;set -a; var=99. Działa we wszystkich rezonansowych powłokach (nie csh i in.).
Strzałka
1
@ Strzałka Chociaż zgodnie z ostatnim wierszem odpowiedzi Boba Eagera spowoduje to, że wszystkie zmienne zostaną następnie ustawione / zmodyfikowane, co może nie być tym, czego chcesz.
TripeHound
8

I zauważam, echo $varże nic nie da. … Co się stało?

W niezbyt dobrym druku bash (1) znajdujemy

set[ --abefhkmnptuvxBCEHPT] [ nazwa opcji ] [ arg …]   [ ] [ nazwa opcji ] [ arg …]-o
set+abefhkmnptuvxBCEHPT+o

            ︙
    Po określeniu opcji ustawiają lub usuwają atrybuty powłoki. Argumenty pozostałe po przetworzeniu opcji traktowane są jako wartości parametrów pozycyjnych i przypisywane są, w kolejności, do $1, $2... .$n

Co oznacza, set -a var=99że nie ustawia zmiennej środowiskowej varna 99; ustawia się $1na var=99. Spróbuj echo "$1"lub echo "$*"zobaczysz.

Scott
źródło