Co jakiś czas wypuszczam skrypt bashowy i uderza mnie kilka sposobów ustawienia zmiennej:
key=value
env key=value
export key=value
Kiedy znajdujesz się w skrypcie lub pojedynczym poleceniu (na przykład często łączę zmienną z programem uruchamiającym Wine, aby ustawić odpowiedni prefiks Wine), wydaje się, że są one całkowicie wymienne, ale na pewno tak nie jest.
Jaka jest różnica między tymi trzema metodami i czy możesz podać mi przykład, kiedy chciałbym konkretnie użyć każdej z nich?
Zdecydowanie związane z Jaka jest różnica między `VAR = ...` a `export VAR = ...`? ale chcę wiedzieć, jak env
do tego pasuje, i kilka przykładów pokazujących zalety każdego z nich byłoby również miłe :)
command-line
bash
Oli
źródło
źródło
export key=value
jest to rozszerzona składnia i nie należy jej używać w przenośnych skryptach (tj#! /bin/sh
.).Odpowiedzi:
Rozważmy konkretny przykład.
grep
Komenda używa zmiennej środowiskowej o nazwieGREP_OPTIONS
ustawić domyślne opcje.Teraz. Biorąc pod uwagę, że plik
test.txt
zawiera następujące wiersze:uruchomienie polecenia
grep one test.txt
powróciJeśli uruchomisz grep z
-v
opcją, zwróci niepasujące linie, więc wynik będzieSpróbujemy teraz ustawić opcję za pomocą zmiennej środowiskowej.
Zmienne środowiskowe ustawione bez
export
nie będą dziedziczone w środowisku wywoływanych poleceń.Wynik:
Oczywiście opcja
-v
nie została przekazanagrep
.Chcesz użyć tego formularza, gdy ustawiasz zmienną tylko dla powłoki, na przykład
for i in * ; do
, jeśli nie chcesz eksportować$i
.Jednak zmienna jest przekazywana do środowiska tego konkretnego wiersza poleceń, więc możesz to zrobić
który zwróci oczekiwany
Ten formularz służy do tymczasowej zmiany środowiska tego konkretnego wystąpienia uruchomionego programu.
Wyeksportowanie zmiennej powoduje jej odziedziczenie:
powraca teraz
Jest to najczęstszy sposób ustawiania zmiennych w celu użycia później uruchomionych procesów w powłoce
Wszystko to odbyło się w bash.
export
jest wbudowanym bash;VAR=whatever
jest składnią bash.env
z drugiej strony jest programem samym w sobie. Poenv
wywołaniu zdarzają się następujące rzeczy:env
zostanie wykonane jako nowy procesenv
modyfikuje środowisko orazenv
Proces otrzymuje przezcommand
proces.Przykład:
To polecenie uruchomi dwa nowe procesy: (i) env i (ii) grep (w rzeczywistości drugi proces zastąpi pierwszy). Z punktu widzenia
grep
procesu wynik jest dokładnie taki sam jak uruchomienieMożesz jednak użyć tego idiomu, jeśli jesteś poza bashem lub nie chcesz uruchamiać kolejnej powłoki (na przykład, gdy używasz
exec()
rodziny funkcji zamiastsystem()
wywołania).Dodatkowa uwaga dotycząca
#!/usr/bin/env
Dlatego też
#!/usr/bin/env interpreter
używa się tego idiomu#!/usr/bin/interpreter
.env
nie wymaga pełnej ścieżki do programu, ponieważ korzysta zexecvp()
funkcji, która przeszukujePATH
zmienną tak, jak robi to powłoka, a następnie zastępuje się uruchomieniem polecenia. Dlatego można go użyć, aby dowiedzieć się, gdzie interpreter (jak perl lub python) „siedzi” na ścieżce.Oznacza to również, że modyfikując bieżącą ścieżkę, możesz wpływać na to, który wariant Pythona zostanie wywołany. Umożliwia to:
zamiast uruchomić Calibre, spowoduje
źródło
env
? Mam na myśli, że kiedy otwierasz nową powłokę, zawsze masz kilka zmiennych. Więc jakiś program musiał jeexport
edytować, prawda?set var=blah
?