Вони охоплюються методом
Інші відповіді допомогли мені зрозуміти, що змінна область оболонки стосується процесів та їх нащадків .
Коли ви вводите команду, як 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змінити значення лише для себе. Це правда?