Как узнать переменные окружения, установленные после входа в сеанс оболочки
Как я могу узнать переменные среды, установленные после входа в сеанс оболочки?
Мои два фиктивных решения были следующими:
_VariableName1="VarValue1";export _VariableName1;
_VariableName2="VarValue2";export _VariableName2;
...
set | grep '_'
… Который почти показывает переменные, установленные после входа в систему (отличающиеся от установленных переменных) .bash_profile а также .bashrc). Такой подход заставляет меня постоянно забывать о подчеркивании в vars - и старые гуру на работе смеются надо мной, когда видят это;)
Второй подход состоит в том, чтобы использовать "читаемые человеком переменные", но запускаться после входа в систему или sudo:
su - username the
set > /tmp/vars.before
установить переменные
VariableName1="VarValue1";export VariableName1;
VariableName2="VarValue2";export VariableName2;
set > /tmp/vars.after
… А затем выполните следующую команду:
comm -13 /tmp/vars.before /tmp/vars.after
или же
comm --nocheck-order -3 /tmp/vars.before /tmp/vars.after
в зависимости от comm бинарный и т. д.
Так какой же самый чистый или самый умный способ выяснить это?
3 ответа
Одним из подходов является переопределение export а также unset с функциями, которые отслеживают ваши переменные.
Обратите внимание: чтобы это работало, вы должны экспортировать переменные следующим образом: export <variable>=<value> ,
Две функции должны быть вызваны export а также unset и поддерживать список ваших переменных в файле, который я назову ~/.track$$ ($$ PID вашей текущей оболочки):
export ()
{
if echo $@ | egrep -q '[^=]+=[^=]+' && builtin export "$@" && echo $- | grep -q i; then # [1]
touch ~/.track$$ # [2]
cp -fa ~/{.track$$,.track$$.bak} 2> /dev/null; # [3]
grep -v "^$(echo $@ | sed 's/\([^=]=\).\+/\1/')" < ~/.track$$.bak > ~/.track$$ 2> /dev/null; # [4]
echo $@ >> ~/.track$$; # [5]
fi
}
unset ()
{
if builtin unset $@ && echo $- | grep -q i; then # [1]
touch ~/.track$$ # [2]
cp -fa ~/{.track$$,.track$$.bak} 2> /dev/null; # [3]
egrep -v "^$@=" < ~/.track$$.bak > ~/.track$$ 2> /dev/null; # [4]
fi
}
Кроме того, вам необходимо выяснить, какие переменные среды вы установили. Такой псевдоним сделает это:
alias iset="cat ~/.track$$ 2>/dev/null"
Псевдоним как это:
alias ireset="rm ~/.track$$ >/dev/null 2>&1"
может быть использован для сброса списка.
Сохранить количество ~/.track$$ файлы до минимума, мы можем использовать эту служебную команду:
rm $(ls -d ~/.* | egrep 'track[0-9]+$|track[0-9]+\.bak$' | egrep -v $(ps -ef | grep bash | grep -v grep | awk '{print $2}' | tr '\n' '|' | sed 's/|$//')) > /dev/null 2>&1
Где мы должны поместить эти функции, псевдонимы и т. Д.?
Я бы порекомендовал вам добавить функции, псевдонимы и служебную команду в конец ~/.bashrc так, чтобы подоболочки тоже получали функции. В зависимости от вашего дистрибутива и как /etc/profile, /etc/bash.bashrc и друзей казнят, вы можете определить их слишком рано (в некоторых дистрибутивах ~/.profile источники ~/.bashrc или наоборот) так что, возможно, вам придется настроить его.
Затем выйдите и войдите снова.
Теперь, если вы бежите export <variable>=<value> в вашей сессии Bash функция export:
[1] проверяет, правильно ли сформирован параметр (чтобы избежать ложных записей при наборе текста
export MYVARпотому что его возвращаемое значение равно 0 и создаст запись в~/.track$$)[1] затем он выполняет
builtin export <variable>=<value>(это устанавливает переменную, независимо от того, что происходит потом)[1] тогда это greps
$-чтобы увидеть, является ли это интерактивной оболочкой (см. этот ответ. Когда я запускаю ssh на машине с Ubuntu, какую оболочку я использую [бесстыдный плагин]). По умолчанию подоболочки не наследуют функции, поэтому сценарии не создаются~/.track$$файлы. Если скрипт использует#!/bin/bash -iВпрочем, так и будет. Это предотвратит это.[2] тогда это касается
~/.track$$чтобы убедиться, что он существует и[3] делает резервную копию
[4] затем он проверяет, существует ли переменная, если это так, она удаляется из
~/.track$$[5] наконец, это добавляет строку
~/.track$$
Точно так же, если вы печатаете unset <variable> и нажмите Ввести функцию unset:
[1] выполняет
builtin unset <variable>(это отменяет переменную, независимо от того, что происходит потом)[1] если
unsetбыл успешным, он проверяет, как вexportфункция выше. является ли это интерактивной оболочкой (см. этот ответ Когда я захожу в машину с Ubuntu, какую оболочку я использую [бесстыдный плагин]). По умолчанию подоболочки не наследуют функции, поэтому сценарии не создаются~/.track$$файлы. Если скрипт использует#!/bin/bash -iВпрочем, так и будет. Это предотвратит это.[2] тогда это касается
~/.track$$чтобы убедиться, что он существует и[3] затем делает резервную копию
~/.track$$[4] удаляет запись переменной из
~/.track$$
Что builtin Ключевое слово, которое я использовал в обеих функциях? поскольку export или же unset мне нужны встроенные функции оболочки (то есть команды, которые поставляются вместе с оболочкой) builtin, которая сама является встроенной командой (из man bash):
встроенная оболочка-встроенная [аргументы]
Выполните указанную встроенную оболочку, передав ей аргументы, и верните ее состояние выхода. Это полезно при определении функции, имя которой совпадает со встроенной оболочкой, сохраняя функциональность встроенной функции. Встроенный CD обычно переопределяется таким образом. Статус возврата - false, если встроенная оболочка не является встроенной командой оболочки.
Команда по ведению домашнего хозяйства перечисляет и фильтрует активный ~/.track$$ файлы и удаляет остальные.
Что вы получаете с этой настройкой:
Нет необходимости использовать подчеркивания больше. Просто используйте знакомый
exportкоманда (которая была переопределена функцией), и она будет работать.каждый
bashсессия имеет свою~/.track$$файл. Никаких столкновений между снарядами.Как побочный эффект от вышеупомянутого, подоболочки не наследуют родительский
~/.track$$файл, хотя они наследуют все переменные среды.Переменные окружения, установленные в исходных файлах (
. fileили жеsource file) добавлены в~/.track$$,Переменные среды, заданные в подоболочке (), также (неправильно) отслеживаются, поскольку
$$расширяется до идентификатора процесса текущей оболочки, а не подоболочки (см.man bash).Переменные перечислены от первого до последнего экспортируемого.
Переменные, установленные
.profileи другие сценарии, которые вы переназначаете (даже с тем же значением), будут перечисленыiset, Например,HOMEобычно устанавливается.profile, Если вы делаетеexport HOME=/usr/local/bin:$HOMEи бегиisetты увидишьHOMEв списке.
А теперь несколько примеров:
Экспортированные переменные отображаются с
iset:$ export MYVAR1=0987654321; iset MYVAR1=0987654321Переопределенные переменные обрабатываются правильно:
$ export MYVAR2="this is a string"; iset MYVAR1=0987654321 MYVAR2=this is a string $ export MYVAR2="this is a different string for the same variable"; iset MYVAR1=0987654321 MYVAR2=this is a different string for the same variableОкружающая среда в соответствии с
envМатчиisetвыход:$ env|grep MYVAR MYVAR2=this is a different string for the same variable MYVAR1=0987654321Переменные только для чтения не добавляются в
~/.track$$:$ export EUID=0; iset -bash: EUID: readonly variable MYVAR1=0987654321Старые, больше не используемые файлы треков удаляются при
~/.bashrcвыполняется (например, при создании подоболочки):$ ls -1 ~/.track* .track11002 .track11002.bak .track21774 .track21774.bak .track2923 .track2923.bak .track7382 .track7382.bak .track8374 .track8374.bak $ echo $$ 2923 $ bash <subshell>$ ls -1 ~/.track* .track2923 .track2923.bak
Если вас интересуют только переменные среды, вы должны использовать env вместо set, Я не совсем уверен, правильно ли я понимаю, чего вы пытаетесь достичь, но кажется, что
env | sort > /tmp/vars.before
после входа в систему, а затем
env | sort > /tmp/vars.after
comm -13 /tmp/vars.before /tmp/vars.after
в какой-то более поздний момент поступает правильно, по крайней мере, если ни одна из переменных среды не содержит строку, содержащую символ новой строки. (Если это так, я бы использовал env -0 | sort -z чтобы получить переменные окружения, разделенные NULL, а затем использовать perl для сравнения или запрограммировать все это на perl.)
Если вы хотите узнать, какие переменные среды были установлены, просто введите следующую команду:
printenv