В чем разница в использовании переменных оболочки и переменных окружения?

отредактируйте файл grub с помощью vi или vim , сохраните изменения и закройте редактор с помощью: wq!

Это то, что вам нужно запустить для обновления grub в RedHat или CentOS:

grub2-mkconfig -o /boot/grub2/grub.cfg
16
07.05.2017, 18:05
4 ответа

Переменные среды представляют собой список пар имя=значение, которые существуют независимо от программы (оболочка, приложение, демон…). Обычно они наследуются дочерними процессами (созданными последовательностью fork/exec): дочерние процессы получают собственную копию родительских переменных.

Переменные оболочки существуют только в контексте оболочки. Они наследуются только в подоболочках (т. е. когда оболочка разветвляется без операции exec). В зависимости от функций оболочки переменные могут быть не только простыми строками, такими как переменные среды, но также массивами, составными, типизированными переменными, такими как целые или с плавающей запятой, и т. д.

При запуске оболочки все переменные среды, которые она наследует от своего родителя, становятся также переменные оболочки (если они не являются недопустимыми в качестве переменных оболочки и других крайних случаев, таких как IFS, которые сбрасываются некоторыми оболочками), но эти унаследованные переменные помечены как экспортированные1. Это означает, что они останутся доступными для дочерних процессов с потенциально обновляемым значением, установленным оболочкой. То же самое относится и к переменным, созданным в оболочке и помеченным как экспортированные с помощью ключевого слова export.

Массивы и другие переменные сложного типа нельзя экспортировать, если только их имя и значение не могут быть преобразованы в шаблон имя=значение или если не используется специальный механизм оболочки (например: bash экспортирует функции в среду, а некоторые экзотические оболочки, отличные от POSIX, такие как rc и es, могут экспортировать массивы).

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

Также обратите внимание, что современные оболочки (как минимум ksh и bash) поддерживают третью область видимости переменных оболочки. Переменные, созданные в функциях с ключевым словом typeset, являются локальными для этой функции (способ объявления функции включает/отключает эту функцию в ksh, и поведение сохраняемости отличается в bash и кш). См. https://unix.stackexchange.com/a/28349/2594

1 Это относится к современным оболочкам, таким как ksh, dash, bash и подобные. Устаревшая оболочка Bourne и оболочки с другим синтаксисом, такие как csh, ведут себя по-разному.

16
27.01.2020, 19:48

Переменные оболочки

Переменные оболочки — это переменные, область действия которых находится в текущем сеансе оболочки, например, в сеансе интерактивной оболочки или сценарии.

Вы можете создать переменную оболочки, присвоив значение неиспользуемому имени:

var="hello"

Переменные оболочки используются для отслеживания данных в текущем сеансе. Переменные оболочки обычно имеют имена со строчными буквами.

Переменные среды

Переменная среды — это экспортированная переменная оболочки. Это означает, что он будет виден как переменная не только в сеансе оболочки, который его создал, но и для любого процесса (не только оболочки), который запускается из этого сеанса.

VAR="hello"  # shell variable created
export VAR   # variable now part of the environment

или

export VAR="hello"

После того, как переменная оболочки была экспортирована, она остается экспортированной до тех пор, пока не будет отменена или пока ее «свойство экспорта» не будет удалено (с помощью export -n в bash), поэтому реэкспортировать его обычно не требуется. Сброс переменной с помощью unset удаляет ее (независимо от того, является ли она переменной среды или нет).

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

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

Набор переменных окружения в процессе часто называют «окружением процесса». Каждый процесс имеет свою среду.

Переменные среды могут быть только «перенаправлены», т. е. дочерний процесс не может никогда изменять переменные среды в своем родительском процессе, и, кроме настройки среды для дочернего процесса при его запуске, родительский процесс не может изменить существующую среду дочернего процесса.

Переменные среды могут быть перечислены с помощью env (без каких-либо аргументов). В остальном они выглядят так же, как неэкспортируемые переменные оболочки в сеансе оболочки. Это немного специфично для оболочки, так как большинство других языков программирования обычно не смешивают «обычные» переменные с переменными окружения (см. ниже).

env также может использоваться для установки значений одной или нескольких переменных среды в среде процесса без их установки в текущем сеансе:

env CC=clang CXX=clang++ make

Это запускает make со средой переменная CC установлена ​​в значение clang и CXX установлена ​​в clang++.

Его также можно использовать для очистки среды для процесса:

env -i bash

Это запускает bash, но не передает текущую среду в новую bash процесс (он по-прежнему будет иметь переменные окружения, поскольку он создает новые из своих сценариев инициализации оболочки).

Пример отличия

$ var="hello"   # create shell variable "var"
$ bash          # start _new_ bash session
$ echo "$var"   # no output
$ exit          # back to original shell session
$ echo "$var"   # "hello" is outputted
$ unset var     # remove variable

$ export VAR="hello"  # create environment variable "VAR"
$ bash
$ echo "$VAR"         # "hello" is outputted since it's exported
$ exit                # back to original shell session
$ unset VAR           # remove variable

$ ( export VAR="hello"; echo "$VAR" )  # set env. var "VAR" to "hello" in subshell and echo it
$ echo "$VAR"         # no output since a subshell has its own environment

Другие языки

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

В C к переменным окружения можно получить доступ с помощью getenv(), setenv(), putenv() и unsetenv(). Переменные, созданные с помощью этих подпрограмм, наследуются любым процессом, запускаемым программой на языке C, таким же образом.

Другие языки могут иметь специальные структуры данных для выполнения той же задачи, например, хэш %ENV в Perl или ассоциативный массив ENVIRON в большинстве реализаций awk.

19
27.01.2020, 19:48

Переменные оболочки трудно дублировать.

$ FOO=bar
$ FOO=zot
$ echo $FOO
zot
$ 

Однако переменные окружения могут дублироваться; это просто список, а в списке могут быть повторяющиеся записи. Вот envdup.c, чтобы сделать именно это.

#include <err.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

extern char **environ;

int main(int argc, char *argv[]) {
    char **newenv;
    int envcount = 0;

    if (argc < 2) errx(64, "Usage: envdup command [args ..]");

    newenv = environ;
    while (*newenv++ != NULL) envcount++;

    newenv = malloc(sizeof(char *) * (envcount + 3));
    if (newenv == NULL) err(1, "malloc failed");
    memcpy(newenv, environ, sizeof(char *) * envcount);
    newenv[envcount]   = "FOO=bar";
    newenv[envcount+1] = "FOO=zot";
    newenv[envcount+2] = NULL;

    environ = newenv;
    argv++;
    execvp(*argv, argv);
    err(1, "exec failed '%s'", *argv);
}

Который мы можем скомпилировать и запустить, сообщив envdup, чтобы затем запустить env, чтобы показать нам, какие переменные окружения установлены...

$ make envdup
cc     envdup.c   -o envdup
$ unset FOO
$ ./envdup env | grep FOO
FOO=bar
FOO=zot
$ 

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

$ unset FOO
$ ./envdup perl -e 'exec "env"' | grep FOO
FOO=bar
$ ./envdup python3 -c 'import os;os.execvp("env",["env"])' | grep FOO
FOO=bar
FOO=zot
$ 

Похоже, Python 3.6 здесь слепо пропускает дубликаты (дырявая абстракция), а Perl 5.24 — нет. Как насчет ракушек?

$ ./envdup bash -c 'echo $FOO; exec env' | egrep 'bar|zot'
zot
FOO=zot
$ ./envdup zsh -c 'echo $FOO; exec env' | egrep 'bar|zot' 
bar
FOO=bar
$ 

Боже, что произойдет, если sudo очистит только первую запись среды, а затем bash запустится со второй? Здравствуйте, эксплойт PATH или LD_RUN_PATH. Ваш sudoвсе остальные?) исправлены для этой дыры? Эксплойты безопасности не являются ни «случайным отличием», ни просто «ошибкой» в вызывающей программе.

5
27.01.2020, 19:48

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

env –Команда позволяет запускать другую программу в пользовательской среде без изменения текущей. При использовании без аргумента он напечатает список текущих переменных среды. printenv –Команда выводит все или указанные переменные среды. set –Команда устанавливает или сбрасывает переменные оболочки. При использовании без аргумента он напечатает список всех переменных, включая переменные среды и оболочки, а также функции оболочки. unset –Команда удаляет переменные оболочки и среды. export –Команда устанавливает переменные среды

1
27.01.2020, 19:48

Теги

Похожие вопросы