POSIX sh는 첫 번째 조건에서 빈 복합 목록을 허용하고 케이스 조건 구성에서 빈 조건을 허용합니까?

POSIX sh는 첫 번째 조건에서 빈 복합 목록을 허용하고 케이스 조건 구성에서 빈 조건을 허용합니까?

읽다케이스 조건부 구성을 위한 POSIX 사양, 이해합니다:

case word in
    [(]pattern1) compound-list;;
    [[(]pattern[ | pattern] ... ) compound-list;;] ...
    [[(]pattern[ | pattern] ... ) compound-list]
esac

내가 아는 한, 의 본문에는 적어도 하나의 조건이 존재하고 case, compound-list해당 조건에 해당하는 조건이 반드시 존재해야 합니다.

나는 빠른 테스트를 작성했습니다.

$ cat test.sh
case $1 in
esac

case $1 in
  .) ;;
  *) echo 1
esac

그 다음에:

$ for shell in /bin/*sh; do
    printf '=%-18s=\n' "$shell"
    "$shell" ./test.sh .
  done
=/bin/ash          =
=/bin/bash         =
=/bin/dash         =
=/bin/heirloom-sh  =
=/bin/ksh          =
=/bin/lksh         =
=/bin/mksh         =
=/bin/pdksh        =
=/bin/posh         =
=/bin/schily-osh   =
=/bin/schily-sh    =
=/bin/sh           =
=/bin/yash         =
=/bin/zsh          =

( /bin/heirloom-sh가보 도구 상자의 Bourne 쉘, /bin/schily-sh and /bin/schily-osh쉴리 본 쉘)

이것은 나를 놀라게 했다! 내가 아는 모든 쉘은 이 구문을 허용합니다. 그리고:

case $1 in esac

위의 모든 쉘에서 작동하지만 ksh(이것은 ksh93u+내 시스템에 있습니다)ksh88Schily가 이 회사에서 근무했음을 확인했습니다..

POSIX는 이것을 허용합니까, 아니면 뭔가 빠졌습니까?

답변1

도움이 되는 경우 구문 규칙은 다음과 같습니다. 잘 읽히지는 않지만 그렇네요것 같다허용됨 - 각각에 대해패턴+목록또 다른 경우가 있습니다모드+인터럽트사례. 세 번째는 완전히 떠날 수도 있음을 나타내는 것 같습니다.패턴화되지 않음. 링크는여기.


case_clause      : Case WORD linebreak in linebreak case_list    Esac
                 | Case WORD linebreak in linebreak case_list_ns Esac
                 | Case WORD linebreak in linebreak              Esac
                 ;
case_list_ns     : case_list case_item_ns
                 |           case_item_ns
                 ;
case_list        : case_list case_item
                 |           case_item
                 ;
case_item_ns     :     pattern ')'               linebreak
                 |     pattern ')' compound_list linebreak
                 | '(' pattern ')'               linebreak
                 | '(' pattern ')' compound_list linebreak
                 ;
case_item        :     pattern ')' linebreak     DSEMI linebreak
                 |     pattern ')' compound_list DSEMI linebreak
                 | '(' pattern ')' linebreak     DSEMI linebreak
                 | '(' pattern ')' compound_list DSEMI linebreak

어쨌든 - 나에게는 효과가 있을 것이다. 다음은 작동합니다:

x=
if $x; then $x; else echo this doesnt happen; fi

... 구문 분석할 때 명령이 비어 있지 않고 쉘에 할 일이 있기 때문입니다. 나는 항상 스키마를 첨부된 목록과 직접 연결합니다. 사실, 그들은 아주 잘 어울립니다.

x=0
for z in a b c d e f g
do    case $z in [abcd]) ;; $((x+=1))) ;; esac
done; echo "$x"

3

사양은 확장 순서와 패턴 목록 연결에 대해 매우 명확합니다. 나는 항상 자연스럽게 두 가지를 결합하여 어느 정도 하나의 명령으로 취급했습니다. 그럼 껍질 때문에하다그 상자를 확인하는 것. 이는 C 스위치 상자가 작동하는 방식과 관련이 있을 수 있습니다.

관련 정보