Я на самом деле не знал, что есть два разных типа переменных, к которым я могу получить доступ из командной строки. Все, что я знал, это то, что я могу объявить переменные, такие как:
foo="my dear friends"
bar[0]="one"
bar[1]="two"
bar[2]="three"
или доступ к ним со знаком $, например:
echo $foo
echo ${bar[1]}
или используя встроенные переменные, такие как:
echo $PWD
PATH=$PATH:"/usr/bin/myProg"
Теперь я слышал, что есть два (по крайней мере?) Типа переменных: переменные оболочки и переменные окружения.
- Какова цель иметь два разных типа?
- Как я знаю, какой тип переменной?
- Каковы типичные обычаи для каждого?
shell
command-line
environment-variables
sharkant
источник
источник
Ответы:
Переменные среды представляют собой список
name=value
пар, которые существуют независимо от того, какой программой является программа (оболочка, приложение, демон…). Как правило, они наследуются дочерними процессами (созданными последовательностьюfork
/exec
): дочерние процессы получают свою собственную копию родительских переменных.Переменные оболочки существуют только в контексте оболочки. Они наследуются только в подоболочках (т. Е. Когда оболочка разветвляется без
exec
операции). В зависимости от свойств оболочки переменные могут быть не только простыми строками, такими как окружения, но также массивами, составными, типизированными переменными, такими как целые числа или числа с плавающей запятой и т. Д.Когда оболочка запускается, все переменные среды, которые она наследует от своего родителя, становятся также переменными оболочки (если они не являются недопустимыми в качестве переменных оболочки и других угловых случаев, например,
IFS
сбрасываемых некоторыми оболочками), но эти унаследованные переменные помечаются как экспортированные 1 . Это означает, что они останутся доступными для дочерних процессов с потенциально обновленным значением, установленным оболочкой. Это также относится к переменным, созданным под оболочкой и помеченным как экспортированные с помощьюexport
ключевого слова.Массив и другие переменные сложного типа не могут быть экспортированы, если их имя и значение не могут быть преобразованы в
name=value
шаблон или если существует специальный механизм оболочки (например:bash
экспортирует функции в среде и некоторые экзотические, не POSIX-оболочки, такие какrc
иes
могут экспортировать массивы ).Таким образом, основное различие между переменными среды и переменными оболочки заключается в их области действия: переменные среды являются глобальными, а неэкспортированные переменные оболочки являются локальными для сценария.
Также обратите внимание, что современные оболочки (как минимум
ksh
иbash
) поддерживают третью область видимости переменных оболочки. Переменные, созданные в функциях сtypeset
ключевым словом, являются локальными для этой функции (способ, которым объявляется функция, включает / отключает эту функциюksh
, и поведение сохранения отличается междуbash
иksh
). См. Https://unix.stackexchange.com/a/28349/2594.1 Это относится и к современной скорлупе нравится
ksh
,dash
,bash
и подобная. Унаследованная оболочка Bourne и оболочки синтаксиса, отличные от Bourne,csh
имеют различное поведение.источник
execve()
системному вызову, поэтому (как правило) используются для сохранения данных при выполнении других команд (в том же процессе).IFS
в некоторых оболочках).rc
,es
могут экспортировать массивы с использованием adhoc-кодировки.bash
аrc
также может экспортировать функции, используя переменные среды (опять же, используя специальную кодировку).ksh93
,typeset
ограничивает сферу только функции , объявленные сfunction foo { ...; }
синтаксисом, а не с Борна (foo() cmd
синтаксис) (и это статическое обзорного не является динамическим , как и в других оболочках).Переменные оболочки
Переменные оболочки - это переменные, область действия которых находится в текущем сеансе оболочки, например, в интерактивном сеансе оболочки или в скрипте.
Вы можете создать переменную оболочки, присвоив значение неиспользуемому имени:
Переменные оболочки используются для отслеживания данных в текущем сеансе. Переменные оболочки обычно имеют имена с строчными буквами.
Переменные среды
Переменная окружения - это переменная оболочки, которая была экспортирована. Это означает, что она будет видна как переменная не только в сеансе оболочки, который ее создал, но и для любого процесса (не только оболочки), который запускается из этого сеанса.
или
После экспорта переменной оболочки она остается экспортированной до тех пор, пока она не будет сброшена или пока ее «свойство экспорта» не будет удалено (с помощью
export -n
inbash
), поэтому обычно нет необходимости повторно экспортировать ее. Сброс переменной с помощьюunset
удаляет ее (независимо от того, является ли она переменной среды или нет).Массивы и ассоциативные хеши в
bash
и другие оболочки нельзя экспортировать, чтобы они стали переменными среды. Переменные среды должны быть простыми переменными, значения которых являются строками, и они часто имеют имена, состоящие из заглавных букв.Переменные среды используются для отслеживания данных в текущем сеансе оболочки, а также для того, чтобы любой запущенный процесс мог получить часть этих данных. Типичным случаем этого является
PATH
переменная окружения, которая может быть установлена в оболочке и впоследствии использована любой программой, которая хочет запускать программы без указания полного пути к ним.Коллекция переменных среды в процессе часто упоминается как «среда процесса». Каждый процесс имеет свою собственную среду.
Переменные среды могут быть только «перенаправлены», то есть дочерний процесс никогда не может изменять переменные среды в своем родительском процессе, и кроме настройки среды для дочернего процесса при его запуске, родительский процесс может не изменять существующую среду дочерний процесс.
Переменные среды могут быть перечислены с
env
(без каких-либо аргументов). Кроме этого, они выглядят так же, как неэкспортированные переменные оболочки в сеансе оболочки. Это немного особенное для оболочки, так как большинство других языков программирования обычно не смешивают «обычные» переменные с переменными среды (см. Ниже).env
также может использоваться для установки значений одной или нескольких переменных среды в среде процесса, не устанавливая их в текущем сеансе:Это начинается
make
с переменной среды,CC
установленной в значениеclang
иCXX
установленной вclang++
.Он также может быть использован для очистки среды для процесса:
Это начинается ,
bash
но не переносит текущую среду для новогоbash
процесса (он все равно будет иметь переменные окружения , как это создает новые из его инициализации оболочки скриптов).Пример различия
Другие языки
В большинстве языков программирования есть библиотечные функции, которые позволяют получать и устанавливать переменные среды. Обратите внимание, что поскольку переменные среды хранятся в виде простых отношений ключ-значение, они обычно не являются «переменными» языка. Программа может извлечь значение (которое всегда является символьной строкой), соответствующее ключу (имя переменной среды), но затем должно будет преобразовать его в целое число или любой другой тип данных, который язык ожидает получить от значения.
В C, переменные окружения могут быть доступны с помощью
getenv()
,setenv()
,putenv()
иunsetenv()
. Переменные, созданные с помощью этих подпрограмм, наследуются таким же образом любым процессом, который запускает программа на Си.Другие языки могут иметь специальные структуры данных для выполнения той же задачи, такие как
%ENV
хэш в Perl илиENVIRON
ассоциативный массив в большинстве реализацийawk
.источник
getenv()
,setenv()
,putenv()
иunsetenv()
. Переменные, созданные с помощью этих подпрограмм, наследуются таким же образом любым процессом, который запускает программа на Си. Другие языки могут иметь специальные структуры данных для той же вещи, как%ENV
в Perl.exec*()
семейство функций также может устанавливать среду для выполняемого процесса.Переменные оболочки трудно дублировать.
Однако переменные среды могут быть дублированы; это просто список, и в списке могут быть повторяющиеся записи. Вот
envdup.c
для этого.Который мы можем скомпилировать и запустить, сказав
envdup
затем запустить,env
чтобы показать нам, какие переменные среды установлены ...Возможно, это полезно только для поиска ошибок или других странностей в том, насколько хорошо программы работают
**environ
.Похоже, Python 3.6 здесь слепо передает дубликаты (дырявая абстракция), а Perl 5.24 - нет. Как насчет снарядов?
Черт возьми, что произойдет, если
sudo
очистить только первую запись среды, а затемbash
запустить со второй? ПриветPATH
илиLD_RUN_PATH
подвиг. Вашsudo
(и все остальное ?) Исправлено для этой дыры ? Эксплойты по безопасности не являются ни «случайным отличием», ни просто «ошибкой» в вызывающей программе.источник
Переменная окружения похожа на переменную оболочки , но это не является специфичным для оболочки . Все процессы в системах Unix имеют хранилище переменных среды . Основное различие между переменными среды и оболочки состоит в том, что операционная система передает все переменные среды вашей оболочки программам, которые запускает оболочка, тогда как переменные оболочки не могут быть доступны в командах, которые вы запускаете.
env –
Команда позволяет запускать другую программу в пользовательской среде без изменения текущей. При использовании без аргумента он напечатает список текущих переменных окружения.printenv –
Команда печатает все или указанные переменные среды.set –
Команда устанавливает или отменяет переменные оболочки. При использовании без аргумента он напечатает список всех переменных, включая переменные окружения и оболочки, а также функции оболочки.unset –
Команда удаляет переменные оболочки и среды.export –
Команда устанавливает переменные средыисточник