2016-10-14 33 views
12

Jak wydrukować właśnie ustawianą zmienną środowiskową?Jak drukować/echo zmiennych środowiskowych?

NAME=sam echo "$NAME" # empty 

Możesz zobaczyć tutaj używając eval to działa. Czy to sposób?

NAME=sam eval 'echo $NAME' # => sam 
+2

'NAZWA = sam echo niezależnie' nie zmienia wartości' NAZWA' w powłoce. – rici

Odpowiedz

16

te muszą iść tak różne polecenia np:

NAME=sam; echo "$NAME" 
NAME=sam && echo "$NAME" 

Ekspansja $NAME do pustego łańcucha odbywa się przez powłokę wcześniej, przed uruchomieniem echo, więc w czasie, gdy zmienna NAME jest przekazywany do środowisko polecenia echo, rozszerzenie zostało już wykonane (do łańcucha zerowego).

Aby uzyskać ten sam rezultat w jednej komendy:

NAME=sam printenv NAME 
+0

Dodałem notatkę o 'printenv'. Mam nadzieję, że jest OK, @heemayl –

+0

@AaronMcDaid Dzięki, usunięto zbędne 'env'. – heemayl

+1

Należy zauważyć, że tylko polecenie oparte na "printenv" zachowuje semantykę polecenia OP: definiując 'NAZWA' jako zmienną środowiskową _sprawdzanąrozporządzeniem_, którą widzi tylko wywoływana komenda i jej procesy podrzędne, ale nie ma żadnych kolejnych poleceń powłoki. Pozostałe komendy robią coś bardzo odmiennego: definiują "NAZWA" jako zmienną "tylko do działania" powłoki-wyjścia, którą widzą wszystkie kolejne komendy _shell_, ale _nie zewnętrzne narzędzia_. – mklement0

2

Składnia

variable=value command 

jest często używany, aby ustawić zmienne środowiskowe dla danego procesu. Musisz jednak zrozumieć, który proces otrzymuje zmienną i kto ją interpretuje. Na przykład, używając dwóch powłok:

a=5 
# variable expansion by the current shell: 
a=3 bash -c "echo $a" 
# variable expansion by the second shell: 
a=3 bash -c 'echo $a' 

Wynik będzie wynosił 5 dla pierwszego echa, a 3 dla drugiego.

2

celu dostosowanie istniejących odpowiedzi wraz z ważnym wyjaśnienia:

Jak stwierdzono, problemem jest to, że z NAME=sam echo "$NAME"$NAME zostanie rozszerzona o bieżącej powłoki przed przypisania NAME=sam zaczyna obowiązywać.

Rozwiązania zachowania pierwotnej semantyki (w odniesieniu do (nieskuteczne) próba rozwiązania NAME=sam echo "$NAME"):

użytkowania albo eval[1] (w samej kwestii) lub printenv (dodany przez Aaron McDaid do heemayl's answer) lub bash -c (od Ljm Dullaart's answer) w kolejności malejącej efektywności:

NAME=sam eval 'echo "$NAME"' # use `eval` only if you fully control the command string 
NAME=sam printenv NAME 
NAME=sam bash -c 'echo "$NAME"' 

printenv nie jest narzędziem POSIX, ale jest dostępne zarówno w systemie Linux, jak iw macOS/BSD.

Co ten styl inwokacji (<var>=<name> cmd ...) nie jest zdefiniowanie NAME:

  • jako środowiska zmienna
  • że jest tylko zdefiniowany w komendzie powołano.

Innymi słowy: NAME istnieje tylko dla polecenia są wywoływane i nie ma wpływu na bieżącej powłoki (jeśli nie zmienna o nazwie NAME istniały wcześniej, nie będzie nic po; preegzystującym NAME zmiennych szczątków bez zmian).

POSIX definiuje reguły dla tego rodzaju inwokacji w rozdziale Command Search and Execution.


następujące roztwory działa bardzo różnie (od heemayl's answer)

NAME=sam; echo "$NAME" 
NAME=sam && echo "$NAME" 

Podczas wytwarzają taką samą wyjście, że zamiast określenia:

  • do powłoki zmienna (tylko) niż środowisko zmienna
    • jeśli echo się polecenie, które podniesiony środowisku zmienna NAME, to nie jest określona (lub potencjalnie określono inaczej wcześniej).
  • że mieszka na po komendzie.

Należy pamiętać, że każda zmienna jest również wystawiony jako zmienna powłoki, ale odwrotna nie jest prawdziwa: zmienne powłoki są widoczne tylko dla bieżącej powłoki i jej podpowłok, ale nie do procesów potomnych, takich jak zewnętrzne narzędzia i (niezasilane) skrypty (chyba że są oznaczone jako zmienne środowiskowe z export lub declare -x).


[1] Technicznie bash narusza POSIX tutaj (jak zsh): Ponieważ eval jest specjalny powłoki wbudowany, poprzedzający NAME=sam zadanie powinny powodować zmiennej $NAME pozostać w zasięgu po zakończeniu polecenia, ale tak się nie dzieje.
Jednak po uruchomieniu bash w trybie zgodności z POSIX, to jest zgodne z.
dash i ksh są zawsze zgodne.
Dokładne reguły są skomplikowane, a niektóre aspekty pozostają w gestii implementacji do podjęcia decyzji; ponownie, zobacz Command Search and Execution.