sudoでコマンドを使用すると、環境変数がありません。たとえば、HTTP_PROXYを設定した後、コマンドwget
はなしで正常に動作しますsudo
。ただし、入力sudo wget
すると、プロキシ設定をバイパスできないと表示されます。
sudoでコマンドを使用すると、環境変数がありません。たとえば、HTTP_PROXYを設定した後、コマンドwget
はなしで正常に動作しますsudo
。ただし、入力sudo wget
すると、プロキシ設定をバイパスできないと表示されます。
回答:
まず、する必要がありexport HTTP_PROXY
ます。次に、man sudo
注意深く読み、-E
旗に注意を払う必要があります。これは機能します:
$ export HTTP_PROXY=foof
$ sudo -E bash -c 'echo $HTTP_PROXY'
これはmanページからの引用です:
-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.
LC_*
変数でも機能しません。ですからexport LOL_FOO=$LC_FOO
、LOL_FOO
代わりに使用してください。
PATH
、.bashrc
ファイル内の1つの要素を追加するという単純なケースでは機能しませんでしたexport PATH=myPath:$PATH
。と入力するとsudo -E bash -c 'echo $PATH'
、PATH
myPathが含まれていません。おそらく、呼び出す前にのsudo
ローカル値がすでに無効になっているためです。むしろ、私はstackoverflow.com/a/33183620/5459638の下の答えが効果的であることを発見しました、つまり、PATH
bash
sudo PATH=$PATH command
トリックは、コマンドをsudoers
使用してファイルに環境変数をsudo visudo
追加し、次の行を追加することです。
Defaults env_keep += "ftp_proxy http_proxy https_proxy no_proxy"
Ubuntu 14の場合、多変数行のエラーを返すため、別の行で指定する必要があります。
Defaults env_keep += "http_proxy"
Defaults env_keep += "https_proxy"
Defaults env_keep += "HTTP_PROXY"
Defaults env_keep += "HTTPS_PROXY"
sudo -E
アドホックに確実に同じ方法で1回限りの効果を得る方法です
etc/sudoers
直接。代わりに、ファイルをvisudo
上書きする前に編集内容を構文チェックするコマンドを使用しsudoers
ます。そうすれば、編集中に間違えてもロックアウトされません。
個別に使用できるようにする個々の変数については、コマンドの一部にすることができます。
sudo http_proxy=$http_proxy wget "http://stackoverflow.com"
package
追加さPATH
れたmyPathの下でテストしました.bashrc
(export
節を含む)。次にsudo PATH=$PATH which package
、とは異なり、正しい答えを見つけsudo which package
ます。ただし、(ファイルが見つからない)sudo PATH=$PATH package
より先に進むことはありませんsudo package
。一方、でpackage
呼び出されたシェルからプレーンを起動するとsudo bash
、拡張パスが保持され、package
sudo権限が付与されます(1つの石で2つのハト)。したがって、応答は実際に起動しているコマンドによって異なります
私はユニークなソリューションを思いつきました。
sudo -E "$@"
コマンドに問題を引き起こしていた変数をリークしていたsudo VAR1="$VAR1" ... VAR42="$VAR42" "$@"
私の場合、長くて醜い#!/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で機能します
スクリプトに環境変数を保持する必要がある場合は、このようなhereドキュメントにコマンドを配置できます。特に、設定する変数がたくさんある場合は、この方法で整然と見えます。
# 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