한 부분이 실패하면 종료되는 쉘 스크립트를 어떻게 작성할 수 있습니까? 예를 들어 다음 코드 조각이 실패하면 스크립트가 종료되어야 합니다.
n=0
until [ $n -ge 5 ]
do
gksu *command* && break
n=$[$n+1]
sleep 3
답변1
한 가지 방법은 set -e
스크립트 시작 부분에 추가하는 것입니다. 이는 (에서 help set
)를 의미합니다.
-e Exit immediately if a command exits with a non-zero status.
따라서 명령이 실패하면 스크립트가 종료됩니다.
또는 exit
가능한 오류 지점에 명시적인 문을 추가할 수 있습니다.
command || exit 1
답변2
키워드를 사용하면 언제든지 스크립트를 종료할 수 있습니다 exit
. 스크립트가 실패했는지, 어떻게 실패했는지 등 exit 1
을 다른 프로그램에 표시하기 위해 종료 코드를 지정할 수도 있습니다. exit 2
(관례적으로 종료 코드 0은 성공을 나타내고 0보다 큰 값은 실패를 나타냅니다. 그러나 관례적으로 127 이상의 종료 코드는 비정상 종료(예: 신호)를 위해 예약되어 있습니다.
실패 시 종료를 위한 일반적인 구조는 다음과 같습니다.
if [ failure condition ]; then
exit n
fi
failure condition
그러나 특정 상황 n
에서는 다르게 수행할 수도 있습니다 . 이제 귀하의 질문을 바꿔서 설명하겠습니다. 다섯 번의 호출 중 하나라도 gksu
실패하면 종료하라는 의미입니다. 한 가지 방법은 다음과 같은 기능을 사용하는 것입니다.
function try_command {
for i in 1 2 3 4 5 ; do
if gksu command ; then
return 0
fi
fi
exit 1
}
그런 다음 호출을 반복합니다 try_command
.
문제를 해결하는 데는 (더) 발전된 방법이나 더 복잡한 방법이 있습니다. 그러나 위의 솔루션은 Stephane의 솔루션보다 초보자에게 더 적합합니다.
답변3
attempt=0
until gksu command; do
attempt=$((attempt + 1))
if [ "$attempt" -gt 5 ]; then
exit 1
fi
done
exit
서브셸에서 호출되지 않는 한 스크립트를 종료합니다. 스크립트의 해당 부분이 서브쉘에 있는 경우 (...)
에만 종료됩니다 . 예를 들어 파이프 내부 또는 파이프의 일부이기 때문입니다.$(...)
해당 하위 쉘.
이 경우 원하는 경우스크립트서브쉘 외에 종료하려면 exit
서브쉘을 호출하여 종료해야 합니다.
예를 들어 다음은 2가지 수준의 중첩된 하위 쉘입니다.
(
life=hard
output=$(
echo blah
[ "$life" = easy ] || exit 1 # exit subshell
echo blih not run
) || exit # if the subshell exits with a non-zero exit status,
# exit as well with the same exit status
echo not run either
) || exit # if the subshell exits with a non-zero exit status,
# exit as well with the same exit status
서브셸이 파이프라인의 일부인 경우 상황이 더 까다로워집니다. 여기에 도움이 될 수 있는 것과 유사한 bash
특별한 배열이 있습니다 .$PIPESTATUS
zsh
$pipestatus
{
echo foo
exit 1
echo bar
} | wc -c
subshell_ret=${PIPESTATUS[0]}
if [ "$subshell_ret" -ne 0 ]; then
exit "$subshell_ret"
fi
답변4
pass_to_functio()
{
echo "command exited with status $1"
}
(
exec <Any Command > &
child_pid=$!
wait $child_pid
pass_to_function $?
)&