O que significa “esac” no final de uma declaração de caso de bash? É necessário?

41

Esta pode ser uma pergunta estúpida, mas eu sou relativamente nova no bash scripting e encontrei vários exemplos de "esac" aparecendo no final de uma declaração de caso, mas não encontrei nenhuma documentação clara sobre seu uso. A página man usa, e até tem um índice na palavra ( link ), mas não define seu uso. É a maneira necessária de encerrar uma declaração de caso, uma melhor prática ou uma técnica pura?

    
por GrnMtnBuckeye 18.01.2016 / 20:34

4 respostas

82

Como fi para if e done para for , esac é a maneira necessária de terminar uma instrução case .

esac é case soletrado para trás, como fi é if soletrado para trás. Não sei por que o token que termina um bloco for não é rof .

    
por 18.01.2016 / 20:43
51

A palavra-chave esac é de fato um delimitador obrigatório para terminar uma instrução case em bash e a maioria dos shells usados no Unix / Linux excluindo a família csh .

O shell Bourne original foi criado por Steve Bourne que trabalhou anteriormente em ALGOL68 . Essa linguagem inventou essa técnica de palavra reversa para delimitar os blocos.

case/esac

if/fi

do/od

O último não é mais do/od mas do/done em Bourne e todas as shells derivadas incluindo bash porque od já existia como um comando Unix desde sua criação (cocal dump ).

Observe que os blocos funcionais do/done são introduzidos pelas instruções for , while ou until . for , while e until não precisam ser terminados, pois done é suficiente. Essa é a razão pela qual não há necessidade dos tokens rof e elihw hipotéticos.

    
por 18.01.2016 / 23:38
5

O " esac " termina um " case " anterior para formar um " bloco de códigos ".

Em Algol68 eles são usados, geralmente a sequência de caracteres invertida da palavra-chave introdutora é usada para terminar o invólucro, e. ( if ~ then ~ else ~ fi, case ~ in ~ out ~ esac, for ~ while ~ do ~ od ).

Eu os chamaria de "Blocos Guardados" depois de Edsger Dijkstra e seus Guarded Command Language .

od presumivelmente não foi usado no Bourne Shell devido à pré-existência do "od" do Unix comando .

A história:

A ideia de "bloqueio vigiado" parece ter vindo de ALGOL 68 Inglês:

proc days in month = (int year, month)int:

  case month in
    31,
    if year mod 4=0 ∧ year mod 100≠0  ∨  year mod 400=0 then 29 else 28 fi,
    31, 30, 31, 30, 31, 31, 30, 31, 30, 31
  esac;

A implementação da LGU Algol68 do Soviete fez o mesmo: Em Inglês, a declaração de caso reverente do Algol68 mostra case ~ in ~ out ~ esac , em Cirílico, este lê выб ~ в ~ либо ~ быв .

Então, em 1975, os blocos de código do Algol68 foram emprestados por Edsger Dijkstra por seus Guarded Command Language . por exemplo.

if a ≥ b → max := a
| b ≥ a → max := b
fi

Presumivelmente, Dijstra usou "Blocos Guardados" para superar a Outra ambiguidade implementada em Algol60 e, em seguida, reengenharia na Linguagem de programação C . (cf. mudança-reduza o conflito. )

Finalmente - de Algol68 - " esac " entrou no shell Bourne de 1977 (onde você descobriu esac ) cortesia de Stephen R. Bourne que desenvolveu um compilador Algol68 inicial chamado ALGOL 68C .

Famoso Stephen também usou esses mesmos Guarded Blocks em um "arquivo de cabeçalho C" chamado macro.h

#define IF  if(
#define THEN    ){
#define ELSE    } else {
#define ELIF    } else if (
#define FI  ;}

Os notáveis gênios de software Landon Curt Noll e Larry Bassel tropeçou no código macro.h de Steve em 1984 enquanto trabalhava no grupo de portas Genix da National Semiconductor e se esforçou para entender sua aplicação. E assim Landon & Larry criou então o Concurso Internacional de Código C Ofuscado ...

De 1984 até hoje tem havido vários milhares outras linguagens de programação "melhores" que não usam os Comandos Guardados de Dijkstra. E o uso de Steven Bourne em macro.h é agora frequentemente citado nas "Dissertações de Desenvolvimento de Software" dos estudantes de TI como prova de que eles não dormem em palestras. : -)

    
por 23.01.2016 / 06:27
1

Sim, é obrigatório. Como Jacob aponta acima, a lógica é a mesma que if / fi . Os delimitadores de comentários C tradicionais /* e */ também são pareados de forma semelhante. Como C foi escrito para que o Unix pudesse ser escrito principalmente em C, com o mínimo de código assembly, com uma grande sobreposição entre as equipes de desenvolvimento C e Unix, é razoável assumir uma fonte comum da noção de que o equivalente de fechamento de um multi -character blockiter deve ser a mesma seqüência de caracteres na ordem inversa.

Por outro lado, loops como for , while e until usam do ... done em vez de reverter a ordem dos caracteres, então há alguma inconsistência

    
por 18.01.2016 / 23:06

Tags