다음 두 스크립트를 고려하십시오.
run.sh:
#!/bin/bash
set -euo pipefail
. "$(dirname $(realpath $BASH_SOURCE))"/init-sudo-script.sh
init-sudo-script.sh
[ ${#BASH_SOURCE[@]} -eq 1 ]\
&& echo "must be sourced by another script."\
&& exit 10
[ $EUID -ne 0 ]\
&& echo "must be executed as root."\
&& exit 20
이것은 정확하며 이것이 내가 예상하는 일입니다.
$ ./run.sh
must be executed as root.
$ echo $?
20
하지만 이해할 수 없습니다.
$ sudo ./run.sh
$ echo $?
1
문제는 [ $EUID -ne 0 ]
스크립트를 제거하면 작동하기 때문이라는 것을 알고 있습니다.
또한 set -e
오류가 발생하면 스크립트가 종료되는 것도 이해합니다.
내가 이해하지 못하는 것은 왜 첫 번째 가드 조건( [ ${#BASH_SOURCE[@]} -eq 1 ]
)이 실패 시 1로 종료되지 않는데 두 번째 가드 조건은 종료되는지입니다.
여기서 무슨 일이 일어나고 있는지 이해하는 사람이 있습니까?
===업데이트===
예상대로 작동하도록 하는 방법을 찾았습니다.
if [ $EUID -ne 0 ]; then
echo "must be executed as root."\
&& exit 20
fi
나는 그것을 남겨두고 Bash를 더 좋게 만드는 데 투자하고 있습니다. 따라서 누군가 무슨 일이 일어나고 있는지 명확히 할 수 있다면 기꺼이 듣고 싶습니다.
답변1
또한
set -e
오류가 발생하면 스크립트가 종료되는 것도 이해합니다.
"아무것도 잘못되지 않았습니다"가 아닙니다. 예외가 있으며 그 중 하나는 다음과 같습니다.
실패한 명령이
&&
또는 목록에서 실행된 명령의 [...] 일부인 경우||
쉘은 다음 마지막 또는 [...] 명령을 제외하고 종료되지 않습니다.&&
||
(원천)
실패 하면 [ ${#BASH_SOURCE[@]} -eq 1 ]
셸이 종료되지 않습니다 set -e
.
마찬가지로 [ $EUID -ne 0 ]
실패하면 쉘은 종료되지 않지만 set -e
.대본이 끝났으니까즉, 실행할 것이 더 이상 남아 있지 않기 때문입니다. 그러면 스크립트의 종료 상태는 마지막으로 실행된 명령의 종료 상태가 됩니다 [
. 그것이 당신이 얻는 이유입니다 1
.
:
테스트가 끝나면 (항상 성공하는 무조치 명령)을 넣고 init-sudo-script.sh
테스트를 다시 실행하십시오. 마지막 명령은 이기 때문에 sudo ./run.sh
반환됩니다 .0
:
if
종료 상태가 다음과 같기 때문에 업데이트된 코드 가 다릅니다 if
.
[...] 조건이 true로 테스트되지 않으면 0입니다.
(원천)