함수 및 변수를 sudo su로 전달 -<

함수 및 변수를 sudo su로 전달 -<

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 -iDefaults !env_resetDefaults env_keep=…sudoers

서브쉘에서 함수를 얻는 일반적인 방법은 서브쉘에서 함수를 정의하는 것입니다. 인용문에 유의하십시오. <<EOFhere 문서를 사용하는 경우 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[@]};
...

관련 정보