셸 스크립트의 일부가 실패하면 종료하는 방법은 무엇입니까?

한 부분이 실패 할 경우 종료되는 쉘 스크립트를 어떻게 작성할 수 있습니까? 예를 들어 다음 코드 스 니펫이 실패하면 스크립트가 종료됩니다.

n=0 until [ $n -ge 5 ] do gksu *command* && break n=$[$n+1] sleep 3 

Answer

한 가지 접근 방식은 스크립트 시작 부분에 set -e를 추가하는 것입니다. 즉, (help set에서) :

 -e Exit immediately if a command exits with a non-zero status. 

따라서 명령이 실패하면 스크립트가 종료됩니다.

또는 가능한 실패 지점에 명시적인 exit 문을 추가 할 수 있습니다.

command || exit 1 

댓글

  • 나 (및 bash 위키 )는 사람들이 적절한 오류 처리에 대해 약간의 생각을 할 것입니다. (IMO 설계로 인해 손상됨) set -e 기능을 사용하는 대신. 하지만 ' 여기에는 실제로 적용되지 않습니다. OP는 명령 실행에 5 번 실패한 후 스크립트를 종료하려고합니다.
  • @St é phaneChazelas 우승 ' 깨 졌는지 여부에 대해 ' 논쟁하지 마세요. ' 확실합니다. ' 맞습니다. 그러나 OP는 " 한 부분이 실패하면 종료되는 셸 스크립트를 어떻게 작성할 수 있습니까? " 물었습니다. 5 회 실패 후 종료하는 것이 '라고 생각하십니까?
  • ' 다른 방법은 생각할 수 없기 때문에 질문을 해석 할 수 있습니다.
  • @St é phaneChazelas 당신이 옳을 수 있습니다. 나는 그것을 문자 그대로 해석했습니다. 스크립트의 일부가 실패하면 전체 스크립트가 어떻게 종료 될 수 있습니까? 그리고 set -e는 제가 아는 유일한 방법입니다.
  • 스크립트 스 니펫에서 set -esleep입니다 (break는 특별한 내장 기능이므로 대부분의 셸에서 실패시 스크립트가 종료됩니다. if 또는 && 왼쪽은 set -e, n=...n가 읽기 전용이면 실패 할 수 있지만 set -e도없이 스크립트를 종료합니다.) 해석은 거의 들리지 않습니다. 질문이 잘못된 단어라는 데 동의합니다.

답변

키워드를 사용하여 언제 어디서나 스크립트를 종료 할 수 있습니다. exit. 스크립트가 어떻게 실패했는지 다른 프로그램에 알리기 위해 종료 코드를 지정할 수도 있습니다. exit 1 또는 exit 2 등 (일반적으로 종료 코드 0은 성공을 의미하고 0보다 큰 것은 실패를 의미합니다. 그러나 규칙에 따라 , 127 이상의 종료 코드는 비정상 종료를 위해 예약되어 있습니다 (예 : 신호).

실패시 종료하는 일반적인 구성은

if [ failure condition ]; then exit n fi 

적절한 failure conditionn. 그러나 특정 시나리오에서는 다르게 진행할 수 있습니다. 이제 귀하의 경우 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로 루프를 호출합니다.

p>

질문을 처리하는 방법에는 (더 많은) 고급 또는 정교한 방법이 있습니다. 그러나 위의 솔루션은 Stephane의 솔루션보다 초보자가 더 쉽게 접근 할 수 있습니다.

Answer

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에는 zsh “의 iv id =”와 유사한 특별한 $PIPESTATUS 배열이 있습니다. cbe7c9bdfe “>

여기에서 도움을받을 수 있습니다.

{ echo foo exit 1 echo bar } | wc -c subshell_ret=${PIPESTATUS[0]} if [ "$subshell_ret" -ne 0 ]; then exit "$subshell_ret" fi 

답변

Trap은 신호를 받으면 작업을 수행합니다.

trap "echo EXIT; exit" 0 trap "echo HUP; exit" 1 trap "echo CTL-C; exit" 2 trap "echo QUIT; exit" 3 trap "echo ERR; exit" ERR n=0 until [ $n -ge 5 ] do n=$[$n+1] echo $n sleep 3 done 

이를 실행하고 정상적으로 종료되도록합니다. 신호 0에 트랩합니다.

EXIT 

다시 실행하고 ^ C로 인터럽트합니다. 신호 2와 신호 0을 모두 트랩합니다.

CTL-C EXIT 

0이 아닌 종료 상태는 ERR에서 트랩됩니다.

ERR EXIT 

답변

pass_to_functio() { echo "command exited with status $1" } ( exec <Any Command > & child_pid=$! wait $child_pid pass_to_function $? )& 

답글 남기기

이메일 주소를 발행하지 않을 것입니다. 필수 항목은 *(으)로 표시합니다