Как сохранить переменные окружения при использовании sudo
Когда я использую любую команду с sudo, переменных среды там нет. Например, после установки HTTP_PROXY команда wget
прекрасно работает без sudo
, Однако, если я наберу sudo wget
он говорит, что не может обойти настройку прокси.
7 ответов
Хитрость заключается в добавлении переменных среды в sudoers
подать через sudo visudo
введите команду и добавьте следующие строки:
Defaults env_keep += "ftp_proxy http_proxy https_proxy no_proxy"
взято из ArchLinux вики.
Для Ubuntu 14 вам нужно указывать в отдельных строках, так как он возвращает ошибки для строк с несколькими переменными:
Defaults env_keep += "http_proxy"
Defaults env_keep += "https_proxy"
Defaults env_keep += "HTTP_PROXY"
Defaults env_keep += "HTTPS_PROXY"
Сначала вам нужно export HTTP_PROXY
, Во-вторых, вам нужно прочитать man sudo
внимательно и обратите внимание на -E
флаг. Это работает:
$ export HTTP_PROXY=foof
$ sudo -E bash -c 'echo $HTTP_PROXY'
Вот цитата из справочной страницы:
-E, --preserve-env
Indicates to the security policy that the user wishes to preserve their
existing environment variables. The security policy may return an error
if the user does not have permission to preserve the environment.
Для отдельных переменных, которые вы хотите сделать доступными по отдельности, вы можете сделать это частью команды.
sudo http_proxy=$http_proxy wget "http://stackru.com"
Вы также можете объединить два env_keep
высказывания в ответе Ахмеда Асуани в едином утверждении, подобные этому:
Defaults env_keep += "http_proxy https_proxy"
Вы должны также рассмотреть возможность указания env_keep
только для одной команды, как это:
Defaults!/bin/[your_command] env_keep += "http_proxy https_proxy"
Простая функция-оболочка (или встроенный цикл for)
Я придумал уникальное решение, потому что:
sudo -E "$@"
утечка переменных, которые вызывали проблемы для моей командыsudo VAR1="$VAR1" ... VAR42="$VAR42" "$@"
был длинным и уродливым в моем случае
demo.sh
#!/bin/bash
function sudo_exports(){
eval sudo $(for x in $_EXPORTS; do printf '%q=%q ' "$x" "${!x}"; done;) "$@"
}
# create a test script to call as sudo
echo 'echo Forty-Two is $VAR42' > sudo_test.sh
chmod +x sudo_test.sh
export VAR42="The Answer to the Ultimate Question of Life, The Universe, and Everything."
export _EXPORTS="_EXPORTS VAR1 VAR2 VAR3 VAR4 VAR5 VAR6 VAR7 VAR8 VAR9 VAR10 VAR11 VAR12 VAR13 VAR14 VAR15 VAR16 VAR17 VAR18 VAR19 VAR20 VAR21 VAR22 VAR23 VAR24 VAR25 VAR26 VAR27 VAR28 VAR29 VAR30 VAR31 VAR32 VAR33 VAR34 VAR35 VAR36 VAR37 VAR38 VAR39 VAR40 VAR41 VAR42"
# clean function style
sudo_exports ./sudo_test.sh
# or just use the content of the function
eval sudo $(for x in $_EXPORTS; do printf '%q=%q ' "$x" "${!x}"; done;) ./sudo_test.sh
Результат
$ ./demo.sh
Forty-Two is The Answer to the Ultimate Question of Life, The Universe, and Everything.
Forty-Two is The Answer to the Ultimate Question of Life, The Universe, and Everything.
Как?
Это стало возможным благодаря встроенной функции bash printf
. В%q
создает строку в кавычках. В отличие от расширения параметров в bash 4.4, это работает в версиях bash < 4.0.
Добавьте фрагменты кода в /etc/sudoers.d.
Не знаю, доступно ли это во всех дистрибутивах, но в дистрибутивах на основе Debian есть строка в конце файла или рядом с ним, которая включает папку
/etc/sudoers.d
. Здесь можно добавить «фрагменты» кода , которые изменяют конфигурацию sudo. В частности, они позволяют контролировать все переменные среды, используемые в .
Как с
/etc/sudoers
, эти "фрагменты кода" следует редактировать с помощью
visudo
. Вы можете начать с прочтения
README
файл, который также является удобным местом для хранения любых заметок, которые вы хотите сделать:
$ sudo visudo -f /etc/sudoers.d/README
# files for your snippets may be created/edited like so:
$ sudo visudo -f /etc/sudoers.d/20_mysnippets
Прочтите раздел «Командная среда» в «man 5 sudoers».
Возможно, наиболее информативная документация по настройке окружения находится в
Command environment
часть
man 5 sudoers
. Здесь мы узнаем, что переменные среды sudoers , заблокированные по умолчанию, могут быть «внесены в белый список» с помощью
env_check
или же
env_keep
опции; например
Defaults env_keep += "http_proxy HTTP_PROXY"
Defaults env_keep += "https_proxy HTTPS_PROXY"
Defaults env_keep += "ftp_proxy FTP_PROXY"
Итак, в случае OP мы можем «передать» переменные окружения sudoer следующим образом:
$ sudo visudo -f /etc/sudoers.d/10_myenvwlist
# opens the default editor for entry of the following lines:
Defaults env_keep += "http_proxy HTTP_PROXY"
Defaults env_keep += "https_proxy HTTPS_PROXY"
# and any others deemed useful/necessary
# Save the file, close the editor, and you are done!
Ориентируйтесь на '# sudo -V'
ОП предположительно обнаружил отсутствующую переменную среды в
sudo
методом проб и ошибок . Тем не менее, можно действовать упреждающе: список всех переменных среды и их разрешенный или запрещенный статус доступен (и уникален для каждого хоста) из
root
подскажите следующее:
# sudo -V
...
Environment variables to check for safety:
...
Environment variables to remove:
...
Environment variables to preserve:
...
Обратите внимание, что как только переменная окружения будет «внесена в белый список», как указано выше, она появится в последующих списках
sudo -V
в списке «сохранить».
Если вам нужно сохранить переменные окружения в скрипте, вы можете поместить свою команду в документ здесь, например так. Особенно, если у вас много переменных, чтобы все выглядело аккуратно.
# prepare a script e.g. for running maven
runmaven=/tmp/runmaven$$
# create the script with a here document
cat << EOF > $runmaven
#!/bin/bash
# run the maven clean with environment variables set
export ANT_HOME=/usr/share/ant
export MAKEFLAGS=-j4
mvn clean install
EOF
# make the script executable
chmod +x $runmaven
# run it
sudo $runmaven
# remove it or comment out to keep
rm $runmaven