отредактируйте файл grub с помощью vi
или vim
, сохраните изменения и закройте редактор с помощью: wq!
Это то, что вам нужно запустить для обновления grub в RedHat или CentOS:
grub2-mkconfig -o /boot/grub2/grub.cfg
Переменные среды представляют собой список пар имя=значение
, которые существуют независимо от программы (оболочка, приложение, демон…). Обычно они наследуются дочерними процессами (созданными последовательностью 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
, ведут себя по-разному.
Переменные оболочки — это переменные, область действия которых находится в текущем сеансе оболочки, например, в сеансе интерактивной оболочки или сценарии.
Вы можете создать переменную оболочки, присвоив значение неиспользуемому имени:
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
.
Переменные оболочки трудно дублировать.
$ 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
(и все остальные?) исправлены для этой дыры? Эксплойты безопасности не являются ни «случайным отличием», ни просто «ошибкой» в вызывающей программе.
Переменная окружения похожа на переменную оболочки , но она не относится к оболочке . Все процессы в системах Unix имеют хранилище переменных среды . Основное различие между переменными среды и оболочки:что операционная система передает все переменные окружения вашей оболочки программам, запускаемым оболочкой, тогда как переменные оболочки не могут быть доступны в командах, которые вы запускаете.
env –
Команда позволяет запускать другую программу в пользовательской среде без изменения текущей. При использовании без аргумента он напечатает список текущих переменных среды. printenv –
Команда выводит все или указанные переменные среды. set –
Команда устанавливает или сбрасывает переменные оболочки. При использовании без аргумента он напечатает список всех переменных, включая переменные среды и оболочки, а также функции оболочки. unset –
Команда удаляет переменные оболочки и среды. export –
Команда устанавливает переменные среды