여러 반환 값을 처리하기 위해 Case 문을 사용하는 방법

여러 반환 값을 처리하기 위해 Case 문을 사용하는 방법

다음 시도를 확인해 보세요.

$ case `true` in 0) echo success ;; *) echo fail ;; esac
fail
$ if `true` ; then
> echo "success"
> else 
> echo "fail"
> fi
success

이제 사례 설명이 실패하는 이유는 무엇입니까? 내가 왜 그 말을 사용하지 않는지 궁금할 수도 있습니다 if. 설명하겠습니다. 내 명령이 복잡할 경우 실행하려는 다른 반환 코드가 반환될 수 있습니다. 명령을 여러 번 실행하고 싶지 않지만 이렇게 할 수는 없습니다.

my_command
res = $?
case $? in
...
esac

이는 set -e스크립트 내에서 사용하고 있기 때문에 my_command실패가 반환되면 스크립트가 중단되기 때문입니다.

하지만 해결책이 있어요...

set +e
my_command
res=$?
set -e
case $? in 
...
esac

하지만 보기 흉하기 때문에 원래 질문으로 돌아가서... 왜 해당 case my_command in ... esac버전만 사용할 수 있나요?

답변1

당신은 사용할 수 없습니다

case $(somecommand) in ...

somecommand명령 대체는 종료 상태가 아닌 명령의 출력으로 확장되므로 종료 상태를 테스트합니다 .

표준 출력에서는 출력이 생성되지 않으므로 를 사용하면 $(true)작동하지 않습니다 .true

넌 할 수있어

{ somecommand; err="$?"; } || true

case $err in
    0) echo success ;;
    *) echo fail
esac

errexit이렇게 하면 ( )에서 실행 중인 스크립트가 -e종료되지 않습니다.

설명서 에서 bash(설명에서 set -e):

실패한 명령이 while 또는 Until 키워드 바로 뒤의 명령 목록의 일부이거나 if 또는 elif 예약어 뒤의 테스트의 일부인 경우 쉘은 종료되지 않습니다.마지막 && 또는 || 뒤에 오는 명령을 제외하고 && 또는 ||의 일부로 실행되는 모든 명령을 나열합니다., 마지막 명령을 제외한 파이프라인의 모든 명령 또는 !로 반전된 명령의 반환 값

이 경우 성공 또는 실패의 가능성만 있는 경우에는 수행하기가 더 쉬울 것입니다.

if somecommand; then
    echo success
else
    echo fail
fi

답변2

문법

`command`

이는 명령의 표준 출력을 원래 명령줄로 바꾸는 것을 의미합니다. 출력은 종료 상태와 동일하지 않습니다. 이 true명령은 출력을 생성하지 않으므로 명령은 다음과 동일합니다.

case "" in
0) echo success ;;
*) echo fail ;;
esac

다음과 같이 문제를 해결할 수 있습니다.

case `my_command; echo $?` in 
...
esac

그런데 if명령에 백틱이 필요하지 않습니다. 다음과 같아야 합니다.

if true
then echo successs
else echo fail
fi

답변3

여전히 이 작업을 수행할 수 는 있지만 set -e다음과 같은 작업을 수행할 수 있습니다.

if my_command
then
    echo success
else
    res=$?
    case $res in
    esac
fi

편집: 당신은 또한 이것을 할 수 있습니다

res=0
my_command || res=$?
case $res in
esac

답변4

나는 전적으로 동의합니다. -e를 비활성화하고 다시 활성화하는 것은 추한 일이므로 피해야 합니다.

여러 가지 옵션

if my_command; then
  echo "my_command ran ok"
else
  rc=$?
  echo "my_command exited with error code $rc"
fi

또는 사례 경로로 가고 싶은 경우(약간 해킹적이지만 사용법보다는 기능을 보여야 합니다).

# PLEASE DO NOT ACTUALLY DO THIS
case "$(my_command > /dev/null && echo 0 || echo $?)" in
  0) echo yeah ;;
  11) echo "bummer" ;;
  *) echo meh ;;
esac

덜 추악한 해결책은 다음과 같습니다(사용 사례를 원하는 경우).

my_command && rc=0 || rc=1
case "$rc" in
...
esac

관련 정보