bash/ksh에 선언된 함수와 변수가 있으며 이를 다음으로 전달해야 합니다 sudo su - {user} << EOF
.
#!/bin/bash
log_f() {
echo "LOG line: $@"
}
extVAR="yourName"
sudo su - <user> << EOF
intVAR=$(date)
log_f ${intVAR} ${extVAR}
EOF
답변1
sudo su -
복잡한 글쓰기 방법을 사용하여 sudo -i
소박한 환경을 조성하세요. 이것이 바로 로그인 쉘의 전부입니다. 일반 sudo
환경에서도 대부분의 변수가 제거됩니다. 외부 명령 도 있습니다 sudo
. 쉘 스크립트 자체의 권한을 상승시킬 수 있는 방법은 없으며, sudo
추가 권한을 사용하여 외부 프로그램( )을 실행하는 것뿐입니다. 즉, 쉘 변수(예: 내보내지 않은 변수) 및 함수가 상위 쉘은 쉘입니다.
또는 sudo bash
대신 로그인 셸을 호출하지 않고 해당 변수가 파일 또는 파일에서 전달되도록 sudo를 구성하여 환경 변수를 전달할 수 있습니다 . 이는 기능에 도움이 되지 않습니다(비록 bash에는 기능 내보내기 기능이 있지만 sudo는 이를 차단합니다).sudo su -
sudo -i
Defaults !env_reset
Defaults env_keep=…
sudoers
서브쉘에서 함수를 얻는 일반적인 방법은 서브쉘에서 함수를 정의하는 것입니다. 인용문에 유의하십시오. <<EOF
here 문서를 사용하는 경우 here 문서의 내용은 먼저 상위 쉘에 의해 확장되고 해당 확장의 결과는 하위 쉘에 표시되는 스크립트가 됩니다. 즉, 글을 쓰면
sudo -u "$target_user" -i <<EOF
echo "$(whoami)"
EOF
대상 사용자 이름 대신 원래 사용자 이름이 표시됩니다. 1단계 확장을 방지하려면 연산자 뒤에 문서 마크업을 인용하세요 <<
.
sudo -u "$target_user" -i <<'EOF'
echo "$(whoami)"
EOF
따라서 상위 셸에서 하위 셸로 데이터를 전달할 필요가 없는 경우 여기에 인용된 설명서를 사용할 수 있습니다.
#!/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
.
답변2
시작한 셸에서 함수가 선언 log_f
되지 않았기 때문에 작동하지 않습니다. sudo su -
대신에:
extVAR="yourName"
sudo su - <user> << EOF
log_f() {
echo "LOG line: $@"
}
intVAR=$(date)
log_f ${intVAR} ${extVAR}
EOF
루트 서브셸에 정의된 함수를 가져와야 합니다. 그게 효과가 있을 수도 있지만... 나는 대부분의 것들이 무엇을 하는지 전혀 모릅니다. 최소한 표준 입력이 요구되지 않거나 암호를 읽는 데 요구되지 않는 한 sudo
이는 선언 su
되어야 합니다 .log_f()
그건 그렇고, 나는 당신이 루트 쉘의 입력으로 이 값을 확장하려고 한다고 믿습니다. 그렇게 하고 싶지 않다면 EOF
변수 자체를 인용해야 합니다.
답변3
제 경우에는 배열을 전달해야 해서 약간의 문제가 있었지만 잠시 후 배열의 값을 -key에 에코 env
하고 예상 코드를 래핑하여 bash -c '<intended code>'
기본적으로 배열을 다시 생성하게 했습니다. 성공 INNER_KEY=($<env_key>)
.
예를 들어:
#!/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[@]};
...