Как узнать переменные окружения, установленные после входа в сеанс оболочки

Как я могу узнать переменные среды, установленные после входа в сеанс оболочки?

Мои два фиктивных решения были следующими:

_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
Другие вопросы по тегам