답변:
sudo su -
복잡한 작성 방법 인 sudo -i
은 깨끗한 환경을 만듭니다. 이것이 로그인 쉘의 요점입니다. 평야조차도 sudo
환경에서 대부분의 변수를 제거합니다. 또한 sudo
외부 명령입니다. 쉘 스크립트 자체에서 특권을 높이는 방법은 없으며 sudo
추가 특권으로 외부 프로그램 ( ) 만 실행하기 때문에 상위 쉘에 정의 된 쉘 변수 (예 : 익스포트되지 않은 변수)와 함수를 사용할 수 없습니다. 자식 껍질.
당신이하지 (로그인 쉘을 호출하여를 통해 환경 변수를 전달할 수 있습니다 sudo bash
대신 sudo su -
나 sudo -i
)와 (과를 통해 이러한 변수를 수 있도록 sudo를을 구성 Defaults !env_reset
하거나 Defaults env_keep=…
에서 sudoers
파일). 이것은 함수에 도움이되지 않습니다 (bash에는 함수 내보내기 기능이 있지만 sudo는이를 차단합니다).
자식 쉘에서 함수를 얻는 일반적인 방법은 함수를 정의하는 것입니다. 인용에주의 <<EOF
하십시오. here 문서에 사용 하는 경우 here 문서의 컨텐츠는 먼저 상위 쉘에 의해 확장되고 해당 확장의 결과는 하위 쉘에 표시되는 스크립트가됩니다. 즉, 당신이 쓰는 경우
sudo -u "$target_user" -i <<EOF
echo "$(whoami)"
EOF
대상 사용자가 아닌 원래 사용자의 이름이 표시됩니다. 이 첫 번째 확장 단계를 피하려면 <<
연산자 다음에 here 문서 마커를 인용하십시오 .
sudo -u "$target_user" -i <<'EOF'
echo "$(whoami)"
EOF
따라서 부모 셸에서 자식 셸로 데이터를 전달할 필요가 없으면 인용 된 here 문서를 사용할 수 있습니다.
#!/bin/bash
sudo -u "$target_user" -i <<'EOF'
log_f() {
echo "LOG line: $@"
}
intVAR=$(date)
log_f "${intVAR}"
EOF
인용되지 않은 here 문서 표시를 사용하여 부모 셸에서 자식 셸로 데이터를 전달할 수 있지만 데이터에 특수 문자가 포함되어 있지 않은 경우에만 작동합니다. 그것은 같은 스크립트에서
sudo -u "$target_user" -i <<EOF
echo "$(whoami)"
EOF
의 출력은 whoami
문자열이 아닌 약간의 쉘 코드가됩니다. 예를 들어, whoami
명령이 반환 "; rm -rf /; "true
되면 자식 셸은 명령을 실행합니다 echo ""; rm -rf /; "true"
.
부모 셸에서 데이터를 전달해야하는 경우 간단한 방법은 인수로 전달하는 것입니다. 하위 쉘을 명시 적으로 호출하고 위치 매개 변수를 전달하십시오.
#!/bin/bash
extVAR="yourName"
sudo -u "$target_user" -i sh _ "$extVAR" <<'EOF'
log_f() {
echo "LOG line: $@"
}
intVAR=$(date)
log_f "${intVAR}" "${1}"
EOF
전달할 변수가 여러 개인 경우 이름별로 변수를 전달하는 것이 더 읽기 쉽습니다. env
자식 쉘의 환경 변수를 설정하려면 명시 적으로 호출하십시오 .
#!/bin/bash
extVAR="yourName"
sudo -u "$target_user" -i env extVAR="$extVAR" sh <<'EOF'
log_f() {
echo "LOG line: $@"
}
intVAR=$(date)
log_f "${intVAR}" "${1}"
EOF
예상 /etc/profile
하고 대상 사용자 ~/.profile
를 읽으 려면 해당 사용자 를 명시 적으로 읽거나 bash --login
대신에 호출해야 합니다 sh
.
실행 log_f
하는 sudo su -
셸 에서 함수 가 선언되지 않았기 때문에 작동하지 않습니다 . 대신 :
extVAR="yourName"
sudo su - <user> << EOF
log_f() {
echo "LOG line: $@"
}
intVAR=$(date)
log_f ${intVAR} ${extVAR}
EOF
루트 서브 쉘에 정의 된 기능을 가져와야합니다. 그럴 수도 있지만 .... 대부분의 일이 무엇인지 모르겠습니다. 적어도 - 너무 오래 둘로 sudo
도 su
암호를 읽을 stdin을 요구 - 얻을 것을 log_f()
선언합니다.
그건 그렇고 그 값을 루트 쉘의 입력으로 확장한다는 의미입니다. 그렇게하지 않으려는 경우 견적 EOF
과 vars 자체를 인용해야 합니다.
필자의 경우 배열을 전달해야하고 문제가 있었지만 배열 값을-키에 에코 env
하고 의도 한 코드를 래핑하여 잠시 후 성공 bash -c '<intended code>'
했습니다. 기본적으로 배열을 다시 INNER_KEY=($<env_key>)
만듭니다.
examlpe의 경우 :
#!/usr/bin/env bash
PLUGINS=(foo bar baz)
sudo -u <some-user> -i env PLUGINS="`echo ${PLUGINS[@]}`" sh <<'EOF'
bash -c '
FOO=($PLUGINS);
echo values: \[${FOO[@]}\];
for pl in ${FOO[@]};
do echo value: $pl;
done;
'
EOF
문제는 다음과 같은 것을 직접 할 수 없다는 것입니다 (을 사용하지 않음 bash -c '...'
).
FOO=($PLUGINS);
for pl in ${FOO[@]};
...