Bash 버전: GNU bash, 버전 4.1.2(1)-릴리스(x86_64-redhat-linux-gnu)
이것은 잘 작동합니다:
#!/bin/bash
exec /usr/local/bin/python2.7 /app/add_container_host.py $@
하지만 특정 사용자로 실행해야 하므로 다음과 같이 변경했습니다.
#!/bin/bash
su -c '/usr/local/bin/python2.7 /app/add_container_host.py $@' $USER
그리고 Python 스크립트는 더 이상 매개변수를 가져오지 않습니다.
작은따옴표를 큰따옴표로 변경해 보았습니다. 이는 Python 스크립트 대신 $@
자체적으로 공급됩니다.su -c
$@
런타임에 이것을 Python 스크립트에 전달하는 방법이 있습니까 su -c
?
답변1
문제는 당신이 사용하는 인용문입니다. 의 변수를 확장할 수 있도록 큰따옴표를 사용해야 합니다 $@
. 그렇지 않으면 리터럴로 남아 확장되지 않습니다.
이것은 예이다
$ cat runme.bash
#!/bin/bash
echo "run with double quotes"
su -c "echo $@" user1
echo "run with single quotes"
su -c 'echo $@' user1
$ ./runme.bash "a b c"
run with double quotes
a b c
run with single quotes
$
또한 인수 목록을 따옴표로 묶은 목록으로 전달해야 합니다. 그렇지 않으면 명령이 su -c ...
혼란스러워지고 원하는 사용자에게 두 번째 인수를 구문 분석하려고 시도하기 시작합니다 su
.
다른 예시
$ ./runme.bash a b c
run with double quotes
su: user b does not exist
run with single quotes
$
디버깅 팁
스크립트가 실제로 수행하는 작업을 보려면 -x
를 전환하여 실행할 수 있습니다 bash
.
$ bash -x ./runme.bash a b c
+ echo 'run with double quotes'
run with double quotes
+ su -c 'echo a' b c user1
su: user b does not exist
+ echo 'run with single quotes'
run with single quotes
+ su -c 'echo $@' user1
$
인용된 주장
$ bash -x ./runme.bash "a b c"
+ echo 'run with double quotes'
run with double quotes
+ su -c 'echo a b c' user1
a b c
+ echo 'run with single quotes'
run with single quotes
+ su -c 'echo $@' user1
$
답변2
su
인수 문자열에서 적절하게 확장되는 매개변수에 의존하기보다는 쉘 위치 매개변수를 명령에 대한 인수로 전달하는 것을 고려할 수 있습니다 -c
.
예를 들어:
#!/bin/sh
su testuser -c 'for arg; do echo "$0 ($(whoami)): $arg"; done' -- su "$@"
그 다음에
$ ./suscript foo "bar baz"
Password:
su (testuser): foo
su (testuser): bar baz
답변3
here-doc 블록에 명령을 래핑하는 것이 도움이 될 수 있습니다.
#!/bin/sh
su testuser -s /bin/sh <<EOF
add_container_host.py "$@"
EOF
아래와 같이 시도해 볼 수도 있습니다.
su testuser -c 'add_container_host.py "$@"' -- argv0 "$@"
그것을 제외하고수 실행또한 좋은 선택입니다.