O POSIX sh permite a lista composta vazia na primeira condição e a condição vazia no caso da construção condicional?

5

Lendo especificação POSIX para construção condicional de caso , vejo:

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

Pelo que entendi, haverá pelo menos uma condição no corpo de case , e o compound-list correspondente a essa condição deve existir.

Eu escrevi um teste rápido:

$ cat test.sh
case $1 in
esac

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

então:

$ 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 é o shell Bourne da caixa de ferramentas da herança , /bin/schily-sh and /bin/schily-osh são o shell do Schily Bourne )

Isso me surpreendeu! Todas as minhas conchas conhecidas aceitaram a sintaxe. E também:

case $1 in esac

funcione em todos os shells acima, mas ksh (que é ksh93u+ no meu sistema), embora trabalhado em ksh88 como confirmado por schily .

Então é permitido pelo POSIX ou eu perdi alguma coisa?

    
por cuonglm 22.12.2015 / 04:29

1 resposta

6

Aqui estão as regras gramaticais, se isso ajudar. Eu não sou bom em lê-lo, mas com certeza parece permitido - para cada caso padrão + lista há também um caso padrão + quebra . Esse terceiro parece indicar que você pode até mesmo ficar totalmente sem padrões . O link é aqui .

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

De qualquer forma - faz sentido para mim que isso funcione. Os seguintes trabalhos:

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

... porque os comandos não estão vazios quando analisados e o shell tem algo a fazer. Eu sempre associo um padrão a uma lista anexada diretamente. E, de fato, eles são muito bem conjugados.

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

A especificação é bem clara sobre a ordem das expansões e associações de listas de padrões. Eu sempre uno naturalmente os dois e os considero mais ou menos como um único comando. E assim, porque o shell faz algo, ele pode marcar essa caixa. Provavelmente tem algo a ver com o funcionamento de um switch switch C.

    
por 22.12.2015 / 07:01

Tags