Мені цікаво встановити змінні середовища для одного екземпляра оболонки з іншого. Тому я вирішив зробити кілька досліджень. Після прочитання ряду на питання про це я вирішив перевірити його.
Я породив два снаряди А і В (PID 420), обидва бігали zsh
. З оболонки AI вибігли наступні.
sudo gdb -p 420
(gdb) call setenv("FOO", "bar", 1)
(gdb) detach
Із оболонки B під час запуску env
я бачу, що змінна FOO дійсно встановлена зі значенням bar. Це змушує мене думати, що FOO було успішно ініціалізовано в середовищі оболонки B. Однак, якщо я спробую надрукувати FOO, я отримаю порожній рядок, маючи на увазі, що він не встановлений. Мені здається, що тут є суперечність.
Це було протестовано як у моїй власній системі Arch GNU / Linux, так і у Ubuntu VM. Я також перевірив це, bash
коли змінна навіть не відображалась у env. Це, хоча для мене розчаровує, має сенс, якщо оболонка кешує копію свого середовища в нерестовий час і використовує лише те (що було запропоновано в одному із пов'язаних питань). Це все ще не відповідає, чому zsh
можна бачити змінну.
Чому вихід echo $FOO
порожній?
EDIT
Після вступу в коментарях я вирішив зробити трохи більше тестування. Результати можна побачити в таблицях нижче. У першому стовпці знаходиться оболонка, в яку FOO
вводилася змінна. Перший рядок містить команду, вихід якої можна побачити під нею. Змінної FOO
вводили з допомогою: sudo gdb -p 420 -batch -ex 'call setenv("FOO", "bar", 1)'
. Команди, характерні для zsh: zsh -c '...'
також були протестовані за допомогою bash. Результати були однаковими, їх результат був опущений для стислості.
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 |
Згадане вище означає, що результати є агностичними. Це не говорить мені набагато більше , ніж zsh
та bash
установка ручки змінних по- різному. Крім того, export FOO
має в цьому контексті дуже різну поведінку залежно від оболонки. Сподіваємось, ці тести можуть зробити щось зрозумілим для когось іншого.
env
) бачать змінене середовище.
zsh
GDB не робить його видимим як змінної оболонки, а робить причиною передачі його дочірнім процесам (як ви помічали), встановивши параметр "дій", bash
він стає видимим у вигляді змінної оболонки, але не спричиняє його передачу дочірнім процесам! Схоже, zsh і bash використовують різні стратегії управління змінними, з zsh відслідковують несередовищі змінні та bash зберігають все у своєму оточенні, яке воно дезінфікує під час запуску (не підзарядки) дочірнього.
export FOO
в bash
?
zsh -c 'echo $FOO'
(використовуєте одинарні лапки!) Замість цього? Ви бачите це тоді?