Санитировать среду с помощью команды или bash script?
В оболочке Bash я хочу дезинфицировать среду в первую очередь при работе с командой.
Я хочу отключить все переменные окружения и установить только те из них, которые имеют решающее значение для функции оболочки, а также те, которые нужны моей программе script для выполнения этой задачи.
Есть ли способ сделать это простым и чистым способом?
Ответы
Ответ 1
Вы можете использовать env
и обертку script:
#!/bin/bash
env -i /path/to/main_script.sh
От man env
:
-i, --ignore-environment
start with an empty environment
Вы также можете, конечно, просто запустить script как env -i script.sh
, если вы его запускаете вручную. К сожалению, насколько я могу судить, нельзя использовать shebang для запуска bash
через env
следующим образом; shebang может принимать только два параметра по определению, проанализированные ядром.
Другое полунадежное решение с использованием env
или exec -c
(что делает почти то же самое), о котором я могу думать, было бы использовать exec -c $0
для повторного запуска script с чистой средой, если вы обнаружите, что он не чист. Предполагая, что $HOME
установлен в нечистой среде и не установлен в чистом (это верно в моей установке):
#!/bin/bash
[ "$HOME" != "" ] && exec -c $0
# rest of the script here
Ответ 2
Отменить все переменные среды bash linux
Команда: env -i bash
Пример: создайте локальные переменные и переменные окружения, затем reset по умолчанию:
[email protected] ~$ LOCAL_DOGE="such variable"
[email protected] ~$ ENVIRONMENT_DOGE="much code"
[email protected] ~$ export ENVIRONMENT_DOGE
[email protected] ~$ set | grep DOGE
ENVIRONMENT_DOGE='much code'
LOCAL_DOGE='such variable'
[email protected] ~$ env | grep DOGE
ENVIRONMENT_DOGE=much code
[email protected] ~$ env -i bash
[email protected] ~$ set | grep DOGE
[email protected] ~$ env | grep DOGE
[email protected] ~$
Итак, wow, LOCAL_DOGE
и ENVIRONMENT_DOGE
исчезают с одной командой.
Отменить все переменные среды bash linux, альтернативный путь.
env - /bin/bash
Пример:
[email protected] ~$ DOGE1="one"
[email protected] ~$ export DOGE2="two"
[email protected] ~$ set | grep DOGE
DOGE1=one
DOGE2=two
[email protected] ~$ env | grep DOGE
DOGE2=two
[email protected] ~$ env - /bin/bash
[email protected] ~$ set | grep DOGE
[email protected] ~$ env | grep DOGE
Ответ 3
Это сработало, когда я попробовал:
for c in $(set | cut -d '=' -f 1); do unset $c; done
Он исказил ошибки для константных переменных, но я смог их игнорировать.
Ответ 4
Расширение на Ответ Эдуардо:
$ env -i bash -c 'printf "%s\n" "${?+?=$?}" "${#+#=$#}" "${*+*=$*}" "${@[email protected][email protected]}" "${-+-=$-}" "${!+!=$!}" "${_+_=$_}" "${$+$=$$}"; env'
?=0
#=0
-=hB
_=bash
$=26927
PWD=/home/username/INVENTORY
SHLVL=1
_=/usr/bin/env
Другими словами, следующие переменные определены в script run с env -i
и показаны env
:
-
$PWD
(рабочий каталог)
-
$SHLVL
(количество оболочек внутри оболочек)
-
$_
(окончательный аргумент предыдущей команды)
Следующие переменные также определены, но не показаны env
:
-
$?
(результат последней команды)
-
$#
(количество аргументов)
-
$-
(флаги переданы в script)
-
$$
(PID script)
Ответ 5
Я столкнулся с этой проблемой, пытаясь создать вспомогательную функцию, чтобы избежать прокси. Я пришел назвать его proxyless
. Его код следует:
proxyless () {
cmd=(unset http_proxy https_proxy \; ${@})
bash -c "${cmd[*]}"
}
То, что я делаю эффективно, это создание массива команд для перехода к bash. Поэтому я использую unset
, чтобы сделать очевидное, и я положил все аргументы команды в конец массива. Так, например,
$ proxyless curl google.com
станет (согласно bash -x
)
$ bash -c 'unset http_proxy https_proxy; curl google.com'
Ответ 6
Вот как это сделать, не запуская новую оболочку, и это будет работать даже с именами странных переменных (содержащих пробелы/новые строки):
while IFS='=' read -rd '' name value ; do unset "$name" ; done < /proc/self/environ
Недостатком является то, что он специфичен для Linux, и полагается на монтируемые procfs.
Это отключит все переменные среды, даже HOME
и PATH
. Это может быть или не быть тем, что вы хотите.
Объяснение: /proc/PID/environ
содержит блок среды процесса, поскольку серия из нуля -d исключает строки NAME=VALUE
. Мы используем цикл read
, устанавливая IFS
разделителя полей в =
чтобы мы могли разделить имя и значение из каждой строки. Установив разделитель строк (-d
) на пустую строку, мы -d
, чтобы read
использовало нулевой символ ("первый" символ строки с нулевым завершением) для разделения строк. Затем просто отмените каждое имя в свою очередь (стараясь его процитировать).