Bash - 두 개의 명령을 실행하고 첫 번째 명령이 실패하면 종료 상태 1을 얻습니다.

Bash - 두 개의 명령을 실행하고 첫 번째 명령이 실패하면 종료 상태 1을 얻습니다.

다음의 경우 report명령은 항상 실행되어야 하지만 명령이 실패하면 종료 상태 1을 가져와야 합니다 test.

test;report
echo $?
0

쉘 스크립트를 작성하지 않고 단일 bash 라인에서 이를 수행하려면 어떻게 해야 합니까?

답변1

저장하고 재사용하세요 $?.

test; ret=$?; report; exit $ret

테스트 명령이 여러 개 있고 모두 실행하고 싶지만 그 중 하나가 실패했는지 추적하려면 bash의 ERR 트랩을 사용할 수 있습니다.

failures=0
trap 'failures=$((failures+1))' ERR
test1
test2
if ((failures == 0)); then
  echo "Success"
else
  echo "$failures failures"
  exit 1
fi

답변2

쉘 명령을 포함하는 파일 외에 쉘 스크립트란 무엇입니까? 쉘 스크립트가 아닌 척 할 수 있습니다그리고다음과 같이 한 줄로 입력하세요.

(test; r=$?; report; [ "$r" -gt 0 ] && exit 1; exit 0)

첫 번째 명령이 1; 이외의 것을 반환하면 하위 쉘을 종료합니다. 0그렇지 않으면 를 반환합니다 0.

예를 들어, 실제 프로그램을 실행하는 대신 무언가를 에코합니다.

$ (false; r=$?; echo report; [ "$r" -gt 0 ] && exit 1; exit 0)
report
$ echo $?
1
$ (true; r=$?; echo report; [ "$r" -gt 0 ] && exit 1; exit 0)
report
$ echo $?
0
$ # example with an exit-status of 2:
$ (grep foo bar; r=$?; echo report; [ "$r" -gt 0 ] && exit 1; exit 0)
grep: bar: No such file or directory
report
$ echo $?
1

셸 옵션을 정기적으로 설정하는 경우 errexit하위 셸이 조기에 종료되지 않도록 재정의를 추가해야 합니다.

(set +o errexit; false; r=$?; echo report; [ "$r" -gt 0 ] && exit 1; exit 0)

답변3

"명령이 실패하면 상태 1로 종료 test"라고 말씀하셨습니다. 이러한 구별을 하려고 한다고 가정하면(즉, test명령이 2 또는 3으로 종료되더라도 종료 값이 1이 되기를 원하는 경우 등) 다음은 좋은 해결책입니다.

test && { report; true; } || { report; false; }

실제로 "1"을 의미하는 것은 아니지만 test전체 종료 코드로 0이 아닌 값이 종료되는 경우 현재 최선의 답변($? 저장 및 재사용)이 제대로 작동합니다.

답변4

이것은 정말 나쁜 생각이지만, 효과가 있는 것 같고 영감을 얻을 수도 있습니다.

(trap report exit; test)

관련 정보