답변:
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[@]};
...