함수와 변수를 sudo su로 전달-<user> << EOF


9

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

답변:


4

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.


1

실행 log_f하는 sudo su -셸 에서 함수 가 선언되지 않았기 때문에 작동하지 않습니다 . 대신 :

extVAR="yourName"

sudo su - <user> << EOF

log_f() {
echo "LOG line: $@"
}

  intVAR=$(date)
  log_f ${intVAR} ${extVAR}
EOF

루트 서브 쉘에 정의 된 기능을 가져와야합니다. 그럴 수도 있지만 .... 대부분의 일이 무엇인지 모르겠습니다. 적어도 - 너무 오래 둘로 sudosu암호를 읽을 stdin을 요구 - 얻을 것을 log_f()선언합니다.

그건 그렇고 그 값을 루트 쉘의 입력으로 확장한다는 의미입니다. 그렇게하지 않으려는 경우 견적 EOF과 vars 자체를 인용해야 합니다.


1

필자의 경우 배열을 전달해야하고 문제가 있었지만 배열 값을-키에 에코 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[@]};
...
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.