쉘 스크립트의 일부가 실패하면 어떻게 종료합니까?

쉘 스크립트의 일부가 실패하면 어떻게 종료합니까?

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

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특별한 배열이 있습니다 .$PIPESTATUSzsh$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 $?
)&

관련 정보