Как узнать переменные окружения, установленные после входа в сеанс оболочки
Как я могу узнать переменные среды, установленные после входа в сеанс оболочки?
Мои два фиктивных решения были следующими:
_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