Я заинтересован в установке переменных среды одного экземпляра оболочки из другого. Поэтому я решил провести небольшое исследование. После прочтения ряда на вопросы о этом я решил проверить его.
Я породил две оболочки A и B (PID 420), обе работают zsh
. Из оболочки ИИ запускается следующее.
sudo gdb -p 420
(gdb) call setenv("FOO", "bar", 1)
(gdb) detach
При запуске из оболочки B я env
вижу, что переменная FOO действительно установлена со значением bar. Это заставляет меня думать, что FOO была успешно инициализирована в среде оболочки B. Однако, если я пытаюсь напечатать FOO, я получаю пустую строку, подразумевая, что она не установлена. Мне кажется, что здесь есть противоречие.
Это было протестировано как на моей собственной системе Arch GNU / Linux, так и на виртуальной машине Ubuntu. Я также проверил это, bash
когда переменная даже не отображалась в env. Это, хотя и разочаровывает меня, имеет смысл, если оболочка кэширует копию своего окружения во время появления и использует только ее (что было предложено в одном из связанных вопросов). Это все еще не отвечает, почему zsh
можно увидеть переменную.
Почему вывод echo $FOO
пустой?
РЕДАКТИРОВАТЬ
После ввода комментариев я решил провести еще несколько тестов. Результаты можно увидеть в таблицах ниже. В первом столбце находится оболочка, в которую 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'
вместо этого вы сделаете (используйте одинарные кавычки!)? Ты видишь это тогда?