[linux] sudo를 사용할 때 환경 변수를 유지하는 방법

sudo와 함께 명령을 사용할 때 환경 변수가 없습니다. 예를 들어, HTTP_PROXY를 설정 한 후이 명령 wget은없이 작동합니다 sudo. 그러나 입력 sudo wget하면 프록시 설정을 무시할 수 없습니다.



답변

먼저해야합니다 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.


답변

비결은 명령을 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"


답변

개별 변수에 대해 하나씩 사용 가능하게하려면 명령의 일부로 만들 수 있습니다.

sudo http_proxy=$http_proxy wget "http://stackoverflow.com"


답변

env_keepAhmed Aswani의 답변에있는 두 가지 진술을 다음과 같은 단일 진술로 결합 할 수도 있습니다 .

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에서 작동합니다.


답변

환경 변수를 스크립트에 보관해야 할 경우 여기에 문서에 명령을 넣을 수 있습니다. 특히 설정할 변수가 많으면 깔끔하게 보입니다.

# 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


답변