Как определить, откуда появилась переменная окружения?

154

У меня есть экземпляр Linux, который я настроил некоторое время назад. Когда я запускаю его и захожу в систему, rootесть некоторые переменные среды, которые я настроил, но я не могу вспомнить или найти, откуда они пришли.

  • Я проверил ~/.bash_profile, /etc/.bash_rcи все сценарии запуска.
  • Я бегал findи grepбезрезультатно.

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

Joel
источник
6
/etc/environmentэто еще один.
Дероберт
8
И /etc/env.d/*файлы. Но, grep -R "YOUR_VARIABLE" /etc/вероятно, лучший способ это выяснить.
rozcietrzewiacz
1
В Mac OS X см. Также Как найти переменную среды?
Жиль
@rozcietrzewiacz самый простой способ ... если переменная действительно находится где-то в / etc / (как в моем случае); если вы отправите это как ответ, я бы проголосовал;)
Строка

Ответы:

55

Если вы используете envкоманду для отображения переменных, они должны отображаться примерно в том порядке, в котором они были созданы. Вы можете использовать это как руководство к тому, были ли они установлены системой очень рано при загрузке, или более поздним .profile или другим файлом конфигурации. В моем опыте, setи exportкоманды будут сортировать свои переменные в алфавитном порядке, так что список не является столь полезным.

Бен Комби
источник
1
Это здорово ... за исключением того, что я пытаюсь выяснить, что очищает переменную окружения (установленную в / etc / environment). :-) (И да, это устанавливается изначально ... Я добавляю строки в различных сценариях, чтобы регистрировать, где он очищается ...)
Майкл Шепер,
128

Если zshваша оболочка для входа:

zsh -xl

С bash:

PS4='+$BASH_SOURCE> ' BASH_XTRACEFD=7 bash -xl 7>&2

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

Поэтому все, что вам нужно сделать, это найти имя вашей переменной среды в этом выводе. (вы можете использовать scriptкоманду, чтобы помочь вам сохранить весь вывод сеанса оболочки, или для этого bashподхода использовать 7> file.logвместо того, 7>&2чтобы сохранять xtraceвыходные данные file.logвместо терминала).

Если вашей переменной там нет, то, вероятно, оболочка унаследовала ее при запуске, поэтому она была установлена ​​ранее, как в конфигурации PAM, ~/.ssh/environmentили в вещах, прочитанных при запуске сеанса X11 ( ~/.xinitrc, ~/.xsession), или в определении службы, которое запустило вашу регистрацию менеджер или даже раньше в каком-то загрузочном скрипте. Тогда find /etc -type f -exec grep -F THE_VAR {} +может помочь.

Стефан Шазелас
источник
4
Впечатляет и полезно, спасибо. Для нас, n00bs, не могли бы вы рассказать немного больше о режиме, и как мы выходим из режима, в который нас помещают? Например, мы не можем просто передать этот вывод.
Джеффри Хейл
5
@ GeoffreyHale Если вы zsh -xl 2>&1, т.е. объединяете выходы stderr и stdout, вы можете использовать grep как обычно.
Ракеш
1
Есть ли способ сделать это с fishоболочкой?
Ник Свитинг
Даже если я использую zsh -xl 2>&1, как-то не могу grep нормально. По-видимому, вывод не содержит правильные переводы строк или что-то.
Xerus
Я думаю, вы могли бы просто использовать PS4='+$BASH_SOURCE> ' BASH_XTRACEFD=7 bash -xl 7>/tmp/$(uuidgen), а затем использовать grep для этого случайного файла.
bd1251252
51

Некоторые места, чтобы посмотреть в первую очередь:

Система в целом

  • /etc/environment: специально для переменных среды
  • /etc/env.d/*: переменные среды, разделенные на несколько файлов
  • /etc/profile: все типы сценариев инициализации
  • /etc/profile.d/*: сценарии инициализации
  • /etc/bashrc, /etc/bash.bashrcпредназначен для функций и псевдонимов

Пользовательский

  • ~/.bash_profile: инициализация для логина (bash-) оболочек
  • ~/.bashrc: инициализация для всех интерактивных (bash-) оболочек
  • ~/.profile: используется для всех снарядов
  • ~/.cshrc, ~/.zshrc, ~/.tcshrc: Аналогичные для не-Баш оболочек
beetstra
источник
31

@ Циан это правильно. Кроме использования findи grep, вы ничего не можете сделать, чтобы выяснить, откуда она взялась. Зная, что это действительно переменная окружения, я попытался бы сфокусировать ваш поиск в / etc / и вашем домашнем каталоге. Замените VARIABLEна соответствующую переменную, которую вы ищете:

$ grep -r VARIABLE /etc/*

$ grep -r VARIABLE ~/.*

Аарон Топонсе
источник
1
Удивительно, что в ответе «ты не можешь», окруженном ответами «да, можешь», даже столько голосов.
Майкл Шепер
Я не вижу никаких ответов, которые бы фактически давали возможность определить, ГДЕ была установлена ​​переменная. Есть некоторые полезные подсказки, но нет единой строки, которая может сделать эту работу.
Эндрю Вагнер
Эта вещь решила мое время. Thanx.
Хасан Раза
@MichaelScheper "Вы не можете" сделать это без поиска / grep. позже в «вы можете» описывается, как это сделать, используя grep
строка
23

Если вы введете set -xсвой .profileили .bash_profile, все последующие команды оболочки будут записаны со стандартной ошибкой, и вы сможете увидеть, устанавливает ли одна из них эти переменные. Вы можете поставить set -xнаверх, /etc/profileчтобы отследить это. Вывод может быть очень подробным, поэтому вы можете перенаправить его в файл с чем-то вроде exec 2>/tmp/profile.log.

Если ваша система использует PAM, ищите pam_envзапросы на загрузку в /etc/pam.confили /etc/pam.d/*. Этот модуль загружает переменные среды из указанных файлов или из системного значения по умолчанию, если файл не указан ( /etc/environmentи /etc/security/pam_env.confв Debian и Ubuntu). Другой файл с определениями переменных среды в Linux - это /etc/login.defs(ищите строки, начинающиеся с ENV_).

жилль
источник
5

Проверьте ваши сценарии запуска на наличие файлов, которые они используют, используя .(точка) или source. Эти файлы могут быть в других каталогах, кроме /etcи $HOME.

Деннис Уильямсон
источник
2

Для zshпользователей может оказаться полезным отслеживание файлов, к которым осуществляется доступ (во время запуска), их не так много, и можно просмотреть их один за другим, чтобы найти, где что-то было определено.

zsh -o SOURCE_TRACE
Эрик Живкович
источник
0

Переменные окружения хранятся в файле / etc / profile, поэтому сделайте больше / etc / profile и просто проверьте, какие переменные env вам нужны, а если / etc / profile отсутствует, то lokk для файла .profile в вашем домашнем каталоге

Сарвеш Павар
источник
1
Переменные среды не хранятся в них /etc/profile, вы можете определить их там в масштабе всей системы, например, bashпри использовании в качестве оболочки для входа. Они сохраняются процессом оболочки после чтения определений из файлов и / или командной строки.
Энтон
-2

Например, если вы хотите найти переменную HISTFILE и ее значение или хотите узнать, какие переменные определены в истории, введите это в оболочке:

set | grep HIST
env | grep HIST
printenv | grep HIST
Вусал Алиев
источник
если вы уже знаете имя, почему не: echo "$HISTFILE"?
Джефф Шаллер
потому что мы хотим найти, где определена переменная $ HISTFILE. Также, если я не хочу знать, какие переменные определены в истории
Вусал Алиев,
2
К сожалению, setне говорит вам, какой файл определил переменную.
Джефф Шаллер