bash: $@를 중단하려면 su -c를 실행하세요.

bash: $@를 중단하려면 su -c를 실행하세요.

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 "$@"

그것을 제외하고수 실행또한 좋은 선택입니다.

관련 정보