이전 명령이 성공한 경우에만 일련의 명령을 순서대로 실행하고 싶습니다. ~에 따르면쉘 스크립트: 오류 처리를 위해 "set -e" 사용의 위험:
다음과 같이 "&&"가 포함된 일련의 명령을 함께 연결하여 오류 검사를 직접 수행하는 것이 좋습니다.
mkdir abc && cd abc && do_something_else && last_thing || { echo error >&2; exit 1; }
특정 명령(예: 루프 또는 복잡한 조건) 사이에 일부 스크립트 논리가 있어야 하는 상황에서 상태를 변수에 캡처한 다음 해당 변수를 다시 사용하여 이전 명령이 실행되는 경우 다른 명령만 실행되도록 하는 관용적 방법은 무엇입니까? 명령이 성공했나요?
그것은 다음과 같습니다:
mkdir abc
status=$?
... # do stuff (which might alter $?)
$status && cd abc
status=$?
... # do more stuff
$status && do_something_else
status=$?
... # do even more
$status && last_thing
status=$?
... # do final stuff
$status || { echo error >&2; exit 1; }
답변1
OP 자체가 제공한 답변의 약간 더 깨끗한 버전은 다음과 같습니다.
bail() {
return=${1-1} # if no parameters sent, default to exit code 1
shift
echo "$@" 1>&2
exit $return
}
if mkdir abc; then
do_stuff
else
bail 1 "Unable to create directory"
fi
if cd abc; then
do_stuff
else
bail 2 "Unable to enter directory"
fi
# et cetera
핵심은 각 실패 사례에 고유한 종료 코드를 제공하는 것이며, 이 구성을 사용하면 else
를 트리거하기 전에 각 절에서 자체 실패 사례 관리를 수행할 수도 있습니다 bail()
.
답변2
이 질문을 작성했을 때 가능한 해결책 중 하나는 다음과 같다는 것을 깨달았습니다.
mkdir abc || { echo error >&2; exit 1; }
... # do stuff (which might alter $?)
cd abc || { echo error >&2; exit 1; }
... # do more stuff
do_something_else || { echo error >&2; exit 1; }
... # do even more
last_thing || { echo error >&2; exit 1; }
... # do final stuff
이 경우 $status
변수는 필요하지 않으며 이전 명령이 성공한 경우에만 명령이 실행됩니다. 또한 die "error message"
오류 메시지를 에코하고 오류 코드와 함께 종료할 수 있는 기능이 유용할 수 있다는 것도 깨달았습니다.
고쳐 쓰다
그리고die
, 이것은 ~이 될 것이다:
die() { echo "$*" >&2; exit 1; }
mkdir abc || die "error"
... # do stuff
cd abc || die "error"
... # do more stuff
do_something_else || die "error"
... # do even more
last_thing || die "error"
... # do final stuff