Переменная оболочки и переменная среды, какая из них предпочтительнее, если оба имеют одно и то же имя?

10

Набрав в Bash следующее:

env | grep USER

и

set | grep USER

дает оба раза одно и то же имя пользователя.

Как узнать, например, при вводе, была echo $USERли отображена оболочка или переменная окружения?

sharkant
источник

Ответы:

14

Для POSIX-совместимых оболочек (включая Bash) стандарт гласит:

2.5.3 Переменные оболочки Переменные
должны инициализироваться из среды [...] Если переменная инициализируется из среды, она должна быть помечена для экспорта немедленно; см экспорт специальный встроенный. Новые переменные могут быть определены и инициализированы с помощью назначения переменных и т. Д.

И о export:

export name[=word]...
Оболочка должна предоставлять атрибут экспорта переменным, соответствующим указанным именам, что должно приводить к тому, что они находятся в среде последующих выполняемых команд.

Так что с точки зрения оболочки есть только переменные. Некоторые из них могли быть получены из среды при запуске оболочки, а некоторые из них могут быть экспортированы в среду процессов, запускаемых оболочкой.

(«Среда» - это на самом деле просто набор строк, передаваемых процессу при его запуске. Когда процесс выполняется, он может делать с ним что угодно, использовать его, игнорировать его, перезаписывать его. И то, что процесс передает запуск других процессов может быть еще одной вещью, хотя, конечно, обычно просто снова передаются все переменные среды.)


Если бы вы использовали какую-то не-POSIX оболочку, например csh, вещи могут отличаться:

$ csh
% echo $foo
foo: Undefined variable.
% setenv foo bar
% echo $foo
bar
% set foo=asdf
% echo $foo
asdf
% env |grep foo
foo=bar
% exit
ilkkachu
источник
1
Обратите внимание, что оболочка Bourne, подобно csh, инициализирует переменные оболочки из переменных среды. Но изменение переменных оболочки не влияет на соответствующую переменную среды, если вы не экспортируете их. Это то, что было сломано оболочкой Korn (и указано в POSIX). Вот почему вы должны быть осторожны с именами переменных оболочки, которые вы используете сейчас, чтобы убедиться, что вы не изменяете env vars, которые могут повлиять на команды, которые вы запускаете в своем скрипте.
Стефан
4

Это одна и та же переменная. В оболочке, в отличие от большинства других языков программирования, переменные среды и переменные оболочки совместно используют одно и то же пространство имен. В оболочке переменная окружения - это переменная оболочки, которая была экспортирована export.

См., Например, мой ответ на ваш предыдущий вопрос «В чем разница в использовании между переменными оболочки и переменными среды? »

Кусалананда
источник
Я перечитал бы ваше объяснение, только сначала мне нужно кое-что узнать, прежде чем я смогу понять ваш ответ.
sharkant
@sharkant Никаких забот. Если я что-то путаю, то просто скажи мне, и я постараюсь уточнить. Ответ Ильккачу тоже хорош.
Кусалананда
нет, я так не думаю, у вас хороший стиль объяснения, только моя нехватка знаний не может их пока лелеять.
sharkant
2

Переменная оболочки может использоваться только для текущей оболочки, она не может использоваться в масштабе всей системы. На другом конце может использоваться переменная среды. По соглашению переменные оболочки записываются в нижнем регистре, а переменные среды - в верхнем. Вы можете заставить переменную оболочки работать как переменную окружения, вам просто нужно ее экспортировать.

Назмул Ахмед Нойон
источник