Interesuje mnie ustawienie zmiennych środowiskowych jednej instancji powłoki od drugiej. Postanowiłem więc przeprowadzić badania. Po odczytaniu numeru z pytaniami o to postanowiłem przetestować go.
Odrodziłem dwie pociski A i B (PID 420), obie działające zsh
. Z powłoki AI uruchomiono następujące.
sudo gdb -p 420
(gdb) call setenv("FOO", "bar", 1)
(gdb) detach
Po uruchomieniu powłoki B env
widzę, że zmienna FOO jest rzeczywiście ustawiona na wartość bar. To sprawia, że myślę, że FOO został pomyślnie zainicjowany w środowisku powłoki B. Jednak jeśli spróbuję wydrukować FOO, otrzymam pustą linię, co oznacza, że nie jest ustawiony. Dla mnie wydaje się, że istnieje tu sprzeczność.
Zostało to przetestowane zarówno na moim systemie Arch GNU / Linux, jak i na maszynie Wirtualnej Ubuntu. Przetestowałem to również bash
tam, gdzie zmienna nawet nie pojawiła się w env. Jest to dla mnie rozczarowujące, ma sens, jeśli powłoka buforuje kopię swojego środowiska w czasie odrodzenia i używa tylko tego (co zasugerowano w jednym z powiązanych pytań). To wciąż nie odpowiada, dlaczego zsh
można zobaczyć zmienną.
Dlaczego wyjście jest echo $FOO
puste?
EDYTOWAĆ
Po wprowadzeniu uwag w komentarzach postanowiłem przeprowadzić nieco więcej testów. Wyniki można zobaczyć w poniższych tabelach. W pierwszej kolumnie znajduje się powłoka, do której FOO
wstrzyknięto zmienną. Pierwszy wiersz zawiera polecenie, którego wynik można zobaczyć pod nim. Zmienna FOO
był wstrzykiwany przy użyciu: sudo gdb -p 420 -batch -ex 'call setenv("FOO", "bar", 1)'
. Polecenia specyficzne dla zsh: zsh -c '...'
zostały również przetestowane przy użyciu bash. Wyniki były identyczne, ich wyniki pominięto ze względu na zwięzłość.
Arch GNU / Linux, zsh 5.3.1, bash 4.4.12 (1)
| | env | grep FOO | echo $FOO | zsh -c 'env | grep FOO' | zsh -c 'echo $FOO' | After export FOO |
|------|------------------|-----------|---------------------------|----------------------|-----------------------------------|
| zsh | FOO=bar | | FOO=bar | bar | No Change |
| bash | | bar | | | Value of FOO visible in all tests |
Ubuntu 16.04.2 LTS, zsh 5.1.1, bash 4.3.48 (1)
| | env | grep FOO | echo $FOO | zsh -c 'env | grep FOO' | zsh -c 'echo $FOO' | After export FOO |
|------|------------------|-----------|---------------------------|----------------------|-----------------------------------|
| zsh | FOO=bar | | FOO=bar | bar | No Change |
| bash | | bar | | | Value of FOO visible in all tests |
Powyższe wydaje się sugerować, że wyniki są niezależne od dystrybucji. Nie mówi mi to nic więcej zsh
i bash
inaczej traktuję ustawianie zmiennych. Co więcej, export FOO
ma bardzo różne zachowanie w tym kontekście, w zależności od powłoki. Mam nadzieję, że testy te wyjaśnią komuś coś innego.
env
) widzą zmodyfikowane środowisko.
zsh
GDB nie powoduje, że jest ona widoczna jako zmienna powłoki, ale powoduje, że jest ona przekazywana do procesów potomnych (jako zaobserwowano), podczas gdy ustawienie jednego bash
powoduje, że jest on widoczny jako zmienna powłoki, ale nie powoduje, że jest on przekazywany do procesów potomnych! Wygląda na to, że zsh i bash używają różnych strategii zarządzania zmiennymi, z śledzeniem zmiennych nieśrodowiskowych za pomocą zsh i przechowywaniem wszystkiego w swoim środowisku, które odkaża podczas uruchamiania potomka (niebędącego podpowłoką).
export FOO
w bash
?
zsh -c 'echo $FOO'
zamiast tego użyjesz (użyj pojedynczych cudzysłowów!)? Widzisz to?