Можно ли восстановить исходную среду в сценарии оболочки POSIX?

Команда zgrep предоставляется пакетом gzip (согласно dpkg -S zgrep ); поддержка переключателя -h была добавлена ​​в 2010-09-05, согласно журналу изменений gzip (из http://ftp.gnu.org/gnu/gzip/ ):

2010-09-15  Paul Eggert  

   zgrep: fix parsing of -Eh options
   * zgrep.in: Update list of single-letter options to match what's
   in GNU grep.  Add -h as an alias for --no-filename.  Bug reported
   by Vladimir Sidorenko in
   .

Есть связанные изменения в пакете Ubuntu и в исходном пакете Debian . В этом журнале изменений указано, что это «регресс». Мне непонятно, так ли это на самом деле, но отсутствующий переключатель отлично работает в Ubuntu 14.04 LTS .

Совет steeldriver за нахождение журналов изменений Debian / Ubuntu.

2
15.02.2018, 09:40
3 ответа

Во время выполнения команды большинство систем позволяют отображать ее среду с помощью команды ps . Это невозможно сделать переносимо, и не все системы позволяют надежный синтаксический анализ, но если все, что вам нужно, - это извлечь «интересные» части исходной среды таким образом, чтобы это работало в конкретном варианте Unix, это просто. Например, в Linux и * BSD:

ps eww $$

В качестве альтернативы в Solaris и Linux:

cat /proc/$$/environ

Или в Solaris и AIX:

pargs -e $$

Если вам нужно скрыть прежнее содержимое среды, убедитесь, что вся оболочка процессы (включая фоновые подоболочки) завершились. Чтобы передавать данные таким образом, чтобы не происходила утечка, используйте канал вместо переменной среды.

exec sh -c 'unset pw; pw=$PASSWORD; unset PASSWORD; printf %s "$pw" | exec theprogram'

Обратите внимание, что в большинстве (всех современных?) Вариантах Unix среда процесса видна только одному и тому же пользователю. Только аргументы обычно видны любому пользователю, выполняющему ps .Так что передавать конфиденциальные данные в среду - это нормально; избавиться от него - это лишь вопрос укрепления, а не элементарной безопасности.

3
27.01.2020, 21:52

Сам POSIX не предоставляет никаких возможностей сделать это из коробки.Я могу придумать несколько способов приблизиться к этому:

  1. Посмотрите на среду, присутствующую в родительском (например, с / proc / pid / окружающая среда в Linux), и повторно заполните среду. с нуля исходя из этого. Это может сработать, а может и не сработать, поскольку
    • Родитель может не обязательно иметь ту же среду, что и дочерний элемент, начатый с
    • Родитель может больше не существовать
    • Дочерний элемент может не иметь доступа к родительской среде (например, в случае отбрасывания привилегий)
  2. Сохраните среду в начале вашего скрипта (например, используя export -p или / proc / self / environment в начале) и восстановить его позже. Это работает достаточно хорошо, но вы должны написать логику, чтобы восстановить это самостоятельно.
  3. Когда вы устанавливаете новую переменную среды, делайте это с помощью функции, которая сначала сохраняет старое значение переменной, а затем вы можете восстановить его с помощью той же функции (или сделать это вручную, например, в $ OLD_PATH ). Это работает, но обременительно, и о нем легко забыть. Например:
$OLD_PATH=$PATH
# do something
$PATH=$OLD_PATH
3
27.01.2020, 21:52

Если вы хотите знать состояние среды до внесения каких-либо изменений, то почему бы вам просто не сохранить его перед тем, как что-либо делать. Например,

#!/bin/sh
PATH_orig=$PATH; # save the original PATH
case ${NEW_VAR++} in
   ? ) echo 'Achtung: NEW_VAR is already in the original environment' ;;
   * ) echo 'NEW_VAR not found in the original environment' ;;
esac

OLD_ENV=$(export -p) # will save your original env in a source-able manner

### And now make your changes...
PATH=/usr/bin
NEW_VAR="foo"; export NEW_VAR
1
27.01.2020, 21:52

Теги

Похожие вопросы