Różnica między zmiennymi powłoki, które są eksportowane, a tymi, które nie są bash

41

Wydaje się, że Bash rozróżnia zmienne, które zostały wyeksportowane, i te, które nie zostały wyeksportowane.

przykład:

$ FOO=BAR
$ env | grep FOO
$ set | grep FOO
FOO=BAR

setwidzi zmienną, ale jej envnie widzi .

$ export BAR=FOO
$ env | grep FOO
BAR=FOO
$ set | grep FOO
BAR=FOO
FOO=BAR

setwidzi obie zmienne, ale envwidzi tylko wyeksportowaną zmienną.

Wiem, że setto wbudowane bash i envnie jest.

Jakie są różnice między zmiennymi, które są eksportowane, a tymi, które nie są?

lesmana
źródło
17
Uwaga dotycząca terminologii: „zmienna środowiskowa” jest zawsze eksportowana. Nieeksportowana zmienna to „zmienna powłoki” (lub „parametr”).
Gilles „SO- przestań być zły”

Odpowiedzi:

44

Wyeksportowane zmienne są przenoszone do środowiska poleceń wykonywanych przez powłokę, która je wyeksportowała, podczas gdy niewyeksportowane zmienne są lokalne dla bieżącego wywołania powłoki. Ze strony podręcznika export:

Powłoka przekaże atrybut eksportu do zmiennych odpowiadających podanym nazwom, co spowoduje, że znajdą się one w środowisku później wykonywanych poleceń.

setgeneruje bieżące środowisko, które obejmuje dowolne lokalne nieeksportowane zmienne. envsłuży do uruchamiania programów w nowym środowisku i bez argumentów wyświetli to, czym byłoby to nowe środowisko. Ponieważ envtworzy nowe środowisko, przenoszone są tylko eksportowane zmienne, tak jak w przypadku każdego programu uruchamianego z tej powłoki. Na przykład, spawnowanie drugiej powłoki w pierwszej (kiedyś $$reprezentowałem podpowiedzi w wewnętrznej powłoce):

$ FOO=BAR
$ bash
$$ echo $FOO             # Note the empty line

$$ exit
$ export FOO
$ bash
$$ echo $FOO
BAR
$$

Zauważ, że eksportowana jest zmienna, a nie tylko jej wartość. Oznacza to, że po ciebie export FOO, FOOstaje się zmienną globalną i pojawia się w kolejnych środowisk, nawet jeśli później zmienić:

$ export FOO
$ FOO=BAR
$ bash
$$ echo $FOO
BAR
$$
Michał Mrożek
źródło
więc jeśli martwisz się tylko o bieżącą powłokę, musisz eksportować? Osobno, dlaczego localedla bieżącej powłoki nie wyświetla aktualizacji?
Pacerier