다음 스크립트가 있습니다.
installRequiredFiles=$1
install_with_pkg()
{
arg1=$1
echo $arg1
echo "[+] Running update: $arg1 update."
}
if [ $installRequiredFiles = "true" ]; then
if [ -x "$(command -v apt)" ]; then
install_with_pkg "apt"
elif [ -x "$(command -v yum)" ]; then
install_with_pkg "yum"
elif [ -x "$(command -v apk)" ]; then
install_with_pkg "apk"
else
echo "[!] Can't install files."
fi
fi
직접 실행하면 잘 작동합니다.
root@ubuntu:/# ./myscript.sh "true"
apt
[+] Running update: apt update.
Printing installRequiredFiles: true
Printing arg1: apt
하지만 사용하면 sh -c
다음과 같은 오류가 발생합니다.
root@ubuntu:/# sh -c ./myscript.sh "true"
./c.sh: 11: [: =: unexpected operator
Printing installRequiredFiles:
Printing arg1:
올바르게 실행하고 싶고 sh -c
현재 지원되는 기능을 지원하고 싶습니다 sh
.bash
답변1
이것은 이 옵션의 목적이 아닙니다 -c
. 일반적으로 파일을 제공하지 않고 쉘 명령을 제공합니다. 그 목적은 다음과 같은 작업을 수행하는 것입니다.
$ sh -c 'echo hello'
hello
이제 파일을 제공하고 파일을 읽고 그 안에 있는 명령을 실행하려고 시도하지만 매개변수는 스크립트( myscript.sh
)에 전달되지 않고 매개변수는 sh
명령 자체에만 전달됩니다. 매개변수:
$ cat script.sh
echo "ARGS: $@"
$ sh ./script.sh true
ARGS: true
$ sh -c ./script.sh true
ARGS:
당신이 해야 할 일은 사용하지 않는 것 -c
뿐이며 예상대로 작동합니다.
sh ./myscript.sh "true"
또는 어떤 이유로든 꼭 사용해야 하는 경우 -c
스크립트를 전달하세요.그리고작은따옴표로 묶인 인수로 스크립트에 대한 매개변수 sh
:
sh -c './myscript.sh "true"'
답변2
귀하가 받고 있는 오류는 쉘 dash
(시스템에 구현된 쉘의 경우 /bin/sh
)에서 발생합니다. 이 $installRequiredFiles
때문 입니다
- 빈 문자열, 그리고
- 따옴표 없이 사용하세요.
변수가 비어 있으므로 따옴표 없이 변수를 사용하면 명령에서 변수가 완전히 제거됩니다.
if [ $installRequiredFiles = "true" ]; then
다음과 같이 해석될 것이다.
if [ = "true" ]; then
이것은 다시 명령 사용의 버그입니다 [
. =
예상되는 사람이 없을 때 연산자가 표시됩니다.
그렇다면 왜 $installRequiredFiles
(및 $1
)이 비어 있습니까?
주문하다
sh -c ./myscript.sh "true"
명령을 실행 ./myscript.sh
하고 스크립트의 문자열로 설정합니다 $0
. true
in의 값은 $0
일반적으로 스크립트나 셸의 이름이며 진단 메시지(예: 셸에서 생성된 오류 메시지)에 가장 일반적으로 사용됩니다.
혹시 사용해보신 분이라면
sh -c ./myscript.sh sh "true"
대신 $1
예상대로 then 은 으로 설정되고 는 (인라인 스크립트에 대한 규칙입니다)로 설정됩니다. 두 경우 모두 스크립트는 -line 없이 스크립트를 실행하는 모든 쉘에 의해 실행됩니다. 스크립트를 실행하게 되는 쉘은 컴퓨터의 쉘에 따라 다를 수 있으며 동일하지 않을 수도 있습니다. 예를 들어 다음을 참조하세요.test
$0
sh
sh -c
#!
sh
sh
bash
Shebang 없이 스크립트를 실행하는 쉘 인터프리터는 무엇입니까?.
#!
다음을 가리키는 스크립트에 줄을 추가 할 수 있습니다 /bin/sh
.
#!/bin/sh
# ... rest of script here ...
# ... just remember to quote all expansions ...
이는 다음과 같이 스크립트를 실행할 수 있음을 의미합니다.
$ ./myscript.sh test
아니면동일한
$ sh -c './myscript.sh "test"'
또는,
$ sh -c './myscript.sh "$@"' sh test
sh -c
마지막 두 경우에는 스크립트를 실행하는 쉘이 아니라 직접 실행하는 #!
것과 마찬가지로 스크립트의 -line이 참조하는 쉘이 무엇이든 상관없습니다 . ./myscript.sh "test"
-line을 추가하기 전과의 차이점은 이제 이것이 다른 #!
쉘이 아니라 쉘인지 확인할 수 있다는 것입니다 ./bin/sh
/bin/sh
스크립트는 POSIX 셸 구문만 사용합니다. 즉, /bin/sh
특정 시스템에서 스크립트를 구현하는 데 사용되는 모든 셸에서 실행할 수 있습니다. /bin/sh
그것이 쉘인지 아니면 bash
좀 ksh
더 dash
이국적인 쉘인지는 중요하지 않습니다. 사용자는 스크립트를 실행하기 위해 올바른 인터프리터를 사용하는 것에 대해 걱정할 필요가 없습니다.
이 답변의 다양한 부분과 관련: