Вони охоплюються методом
Інші відповіді допомогли мені зрозуміти, що змінна область оболонки стосується процесів та їх нащадків .
Коли ви вводите команду, як ls
у командному рядку, ви фактично змушуєте процес запустити ls
програму. Новий процес має свою оболонку як свого батьківського.
Будь-який процес може мати свої "локальні" змінні, які не передаються дочірнім процесам. Він також може встановити змінні "оточення", які є. Використання export
створює змінну середовища. У будь-якому випадку непов'язані процеси (однорангові оригінали) не будуть бачити змінну; ми лише контролюємо те, що бачать дитячі процеси.
Припустимо, у вас є bash shell, який ми будемо називати A. Ви вводите bash
, що створює дочірню обробку bash shell, яку ми будемо називати B. Все, що ви викликали export
в A, все одно буде встановлено у B.
Тепер, у В, ти кажеш FOO=b
. Відбудеться одна з двох речей:
- Якщо B не отримав (від A) змінну середовища, яку називають
FOO
, вона створить локальну змінну. Діти В не отримають його (якщо тільки Б не дзвонить export
).
- Якщо B було отримати (від А) змінне оточення callled
FOO
, він буде змінювати його для себе і згодом роздвоєних дітей . Діти B побачать значення, яке призначив B. Однак це зовсім не вплине на А.
Ось швидка демонстрація.
FOO=a # set "local" environment variable
echo $FOO # 'a'
bash # forks a child process for the new shell
echo $FOO # not set
exit # return to original shell
echo $FOO # still 'a'
export FOO # make FOO an environment variable
bash # fork a new "child" shell
echo $FOO # outputs 'a'
FOO=b # modifies environment (not local) variable
bash # fork "grandchild" shell
echo $FOO # outputs 'b'
exit # back to child shell
exit # back to original shell
echo $FOO # outputs 'a'
Все це пояснює мою первісну проблему: я розмістив GEM_HOME
свою оболонку, але коли я подзвонив bundle install
, це створило дочірній процес. Оскільки я не використовував export
, дочірній процес не отримував оболонки GEM_HOME
.
Неекспорт
Ви можете "неекспортувати" змінну - не допустити її передачі дітям - за допомогою export -n FOO
.
export FOO=a # Set environment variable
bash # fork a shell
echo $FOO # outputs 'a'
export -n FOO # remove environment var for children
bash # fork a shell
echo $FOO # Not set
exit # back up a level
echo $FOO # outputs 'a' - still a local variable
FOO=bar
, в оболонці встановлено значення поточного процесу оболонки. Якщо я запускаю таку програму, як (bundle install
), це створює дочірній процес, до якого не можна отримати доступFOO
. Але якби я сказавexport FOO=bar
, дитячий процес (і його нащадки) мали б доступ до нього. Один із них міг, у свою чергу, закликатиexport FOO=buzz
змінити значення для своїх нащадків або простоFOO=buzz
змінити значення лише для себе. Це правда?