Как показать текущее значение переменной среды?

24

Когда я проверяю среду моей системы, появляется много переменных среды. Как я могу просто найти конкретную переменную?

Книга, которую я читаю, говорит:

Иногда количество переменных в вашей среде становится достаточно большим, настолько, что вы не хотите видеть все значения, отображаемые, когда вас интересует только одна. Если это так, вы можете использовать echoкоманду, чтобы показать текущее значение переменной среды.

Как мне сделать это в терминале Linux?

iLearnSlow
источник

Ответы:

25

Только что:

echo "$VARIABLENAME"

Например, для переменной среды $HOMEиспользуйте:

echo "$HOME"

Который затем печатает что-то похожее на:

/home/username

Редактировать : согласно комментарию Стефана Шазеля , может быть лучше, если вы используете printenvвместо echo:

printenv HOME
хаос
источник
4
Вы забыли кавычки (если вы не подразумеваете синтаксис zsh или rc / es). echoплохой выбор команды, поскольку он может преобразовать содержимое переменной. Он выведет содержимое параметра оболочки с тем же именем. Это не обязательно то же самое при использовании Bourne оболочки или окр вары , как 1, *например. И вы не можете использовать этот подход для переменных env, чье имя недопустимо в качестве имени переменной оболочки.
Стефан Шазелас
5
Также обратите внимание, что если имеется несколько записей среды с одинаковым именем (ОК, патологический случай), то, что вы получите, зависит от оболочки (обычно либо первая, либо последняя). printenv VARотобразит их все (по крайней мере, для реализации GNU).
Стефан Шазелас
9

Выполняя:

printenv

Вы увидите все переменные среды. Для получения дополнительной информации вы можете взглянуть на:

https://www.digitalocean.com/community/tutorials/how-to-read-and-set-environmental-and-shell-variables-on-a-linux-vps

Светлин Тончев
источник
2
Чтобы приблизиться к фактическому ответу на вопрос, printenv variablenameбудет отображаться только именованная переменная; Например, printenv  HOMEбудет делать примерно то же самое, что и echo  "$HOME".
G-Man говорит «Восстановить Монику»
5

Важно понимать, что у каждого процесса есть свой набор переменных среды.

Когда процесс вызывает fork()системный вызов, создается второй процесс ( дочерний ), идентичный первому ( родительский ) (эта копия включает среду, которая находится чуть выше стека (или чуть ниже), в зависимости от того, как вы думаете о стеках :-)- но в Unix / Linux стек растет вниз от высоких адресов).

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

Однако, когда он восстанавливает стек, он копирует окружение и строки аргументов, переданные execve()в стек сначала (в указанном порядке), прежде чем вызывать main()функцию (большая часть работы выполняется в crt0коде начальной загрузки после execve()возврата (к записи). точка указана в двоичном виде)).

В execve()библиотеке C есть обертки для системного вызова, которые передают текущую среду (т. Е. Копию родительской среды), а не вызывающую ее вызывающую (так что в действительности дочерний процесс наследует родительскую среду) - смотрите environ(7).

Попробуйте запустить (как root) команду ps axeww | less... это покажет вам среду для всех процессов! Интересным является процесс с идентификатором 1 (т.е. initпроцесс - первый процесс, созданный ядром во время загрузки).

Если вы хотите посмотреть на среду для определенного процесса (и знаете, что это идентификатор процесса), попробуйте выполнить команду cat /proc/<PID>/environ(заменив <PID>ее идентификатором процесса).

Обратите внимание, что если процесс имеет достаточные привилегии, он может переписать свой собственный стек, что может затруднить понимание его среды - вы увидите некоторые процессы-демоны, подобные этому, в выводе ps.

Но, в конце концов, вся эта вафля сводится к тому, что @chaos сказал выше, если вы хотите посмотреть текущее значение определенной переменной среды в вашем процессе оболочки, просто используйте (встроенную) команду echo "$<NAME>"(заменив <NAME>ее именем переменная окружения, которая вас интересует) ... просто имейте в виду, что одна и та же переменная может иметь другое значение или не существовать вообще в другом процессе.

Мюррей Дженсен
источник
1
(1) Обратите внимание, что eопция psи /proc/…/environспециальный файл могут существовать не во всех системах. (2) AFAIK, каждый процесс Unix имеет право переписывать свой стек и изменять переменные окружения. (3) Для получения дополнительной информации см. К кому относятся переменные среды? (на Супер пользователя ).
G-Man говорит «Восстановить Монику»
У меня было в голове, что в некоторых системах есть способ не позволить непривилегированному процессу «скрыть» свои аргументы командной строки и среду, например, от запуска root ps… но теперь, когда вы подчеркнули этот момент, я не могу вспомнить, почему я думал, что.
Мюррей Дженсен
@MurrayJensen в соответствии с некоторым обсуждением вопроса с высоким голосом, который я задал о «завитке», скрывающем свои аргументы в ps - в POSIX не указано, возвращает ли ps аргументы, как они были первоначально переданы процессу, или копию, которую процесс мог изменить после него начал. Некоторая система (я думаю, что Solaris ??) показывает оригинальные аргументы, несмотря ни на что. (Вот ссылка.) Возможно, это то, о чем вы думали. :)
Wildcard
Бинго! Да, конечно, Solaris делает это «правильно» :-) Спасибо за повышение квалификации ...
Мюррей Дженсен
1

Вы можете получить то, что вы ищете с export:

export | grep HOME

Покажет содержимое $HOMEпеременной.

Дарт Эгрегиус
источник
1

если вам нужно установить много переменных:

  ( set -o posix ; set ) | sort >~/vars.before

после установки их:

  ( set -o posix ; set ) | sort >~/vars.after

чем показать, что было установлено:

  comm -3 ~/vars.before ~/vars.after | perl -ne 's#\s+##g;print "\n $_ "'

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

  # ---------------------------------------------------------
  # cat cnf/qto.dev.host-name.cnf
  # [MainSection]
  # postgres_db_name     = dev_qto
  # postgres_db_host     = host-name
  #
  # call by: doParseCnfEnvVars cnf/qto.dev.host-name.cnf
  # ---------------------------------------------------------
  doParseCnfEnvVars(){

     cnf_file=$1;shift 1;
     test -z "$cnf_file" && echo " you should set the cnf_file !!!"

     INI_SECTION=MainSection

     ( set -o posix ; set ) | sort >~/vars.before

     eval `sed -e 's/[[:space:]]*\=[[:space:]]*/=/g' \
        -e 's/#.*$//' \
        -e 's/[[:space:]]*$//' \
        -e 's/^[[:space:]]*//' \
        -e "s/^\(.*\)=\([^\"']*\)$/export \1=\"\2\"/" \
        < $cnf_file \
        | sed -n -e "/^\[$INI_SECTION\]/,/^\s*\[/{/^[^#].*\=.*/p;}"`

     # and post-register for nice logging
     ( set -o posix ; set ) | sort >~/vars.after

     echo "INFO added the following vars from section: [$INI_SECTION]"
     comm -3 ~/vars.before ~/vars.after | perl -ne 's#\s+##g;print "\n $_ "'
  }
Йордан Георгиев
источник