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

55

Eu encontrei vários exemplos de "esac" aparecendo no final de uma declaração de caso bash, mas não encontrei nenhuma documentação clara sobre seu uso. A página de manual o usa e até possui um índice na palavra ( https://www.gnu.org/software/bash/manual/bashref.html#index-esac ), mas não define seu uso. É a maneira necessária para encerrar uma declaração de caso, prática recomendada ou técnica pura?

GrnMtnBuckeye
fonte
2
A entrada do índice para os esacpontos exatamente onde deveria - para a linha que o define e ilustra que é necessário.
hobbs
@ Hobbs, você está certo de que o índice aponta para a linha que ilustra seu uso, mas não o define de forma alguma, especialmente se comparado ao modo como descreve o uso de outros caracteres como "|" ou ";" ou ";;". Agora que li a (s) resposta (ões), o "case" ortográfico inverso parece ser um padrão de fato para finalizar comandos que os usuários mais experientes não consideram certo.
GrnMtnBuckeye
Se você não teve esacou algo parecido, como você acha que seria capaz de dizer onde está o final da casedeclaração?
Barmar
Ele define como sendo parte da sintaxe da casedeclaração, da mesma forma que else, elife fisão definidos como sendo parte da sintaxe de uma ifdeclaração. Ele não possui nenhuma semântica própria, portanto não há nada a dizer sobre isso, mas está no final da definição de uma casedeclaração, então é onde a casedeclaração termina. O fato de ter sido caseescrito para trás é uma curiosidade conveniente, mas o computador não se importa, apenas sabe que está procurando uma determinada palavra.
hobbs
11
@hobbs "... não há nada a dizer sobre isso ...", mas você acabou de escrever um parágrafo de explicação de por que não há nada a dizer sobre isso. O importante é apenas entender a intenção do "esac". É por isso que esta pergunta tem uma resposta direta com um número razoável de votos.
Angelo

Respostas:

99

Como fipara ife donepara for, esacé a maneira necessária de terminar uma casedeclaração.

esacé casesoletrado para trás, assim como fié ifsoletrado para trás. Não sei por que o token que termina um forbloco não é rof.

Jacob Minshall
fonte
33
Você quer dizer por que não odtermina um dobloco? :)
Curinga
4
Imagine ter que digitar \odtoda vez que quiser usar esse utilitário! O que é raro, mas o meu argumento permanece;)
Pontuação_De 18/01/16
2
Tirou você de 666. De nada: P. E ótima resposta!
TheWanderer 19/01
12
@Wildcard É fie não neht, então, por analogia, seria rof(ou elihw) e não od(também, odé claro, já está sendo usado) ... mas talvez isso esteja esperando muita autoconsistência de uma das linguagens mais inconsistentes Há sim.
Zwol
11
ROTFL nada mais a dizer
gerhard d.
55

A esacpalavra-chave é realmente um delimitador necessário para finalizar uma casedeclaração bashe a maioria dos shells usados ​​no Unix / Linux, exceto a cshfamília.

O shell Bourne original foi criado por Steve Bourne, que trabalhou anteriormente no ALGOL68 . Essa linguagem inventou essa técnica de palavras invertidas para delimitar blocos.

case/esac

if/fi

do/od

Este último não é mais do/od, mas do/doneem Bourne e todas as conchas derivados, incluindo bash, porque odjá existia como um comando Unix desde a sua criação ( o ctal d UMP ).

Observe que os do/doneblocos funcionais são introduzidos pelas instruções for, the whileou the until. for, whilee untilnão precisa ser finalizado como doneé suficiente. Essa é a razão pela qual não há necessidade de hipotéticos rofe elihwtokens.

jlliagre
fonte
6

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

No Algol68, eles são usados, geralmente a sequência de caracteres invertida da palavra-chave de introdução é usada para terminar o gabinete, por exemplo, ( if ~ then ~ else ~ fi, case ~ in ~ out ~ esac, for ~ while ~ do ~ od ).

Eu os chamaria de "Blocos Guardados", em homenagem a Edsger Dijkstra e sua Linguagem de Comando Guardada .

odpresumivelmente não foi usado no Bourne Shell por causa da pré-existência do comando "od" do Unix .

A história:

A idéia do "Bloco Guardado" parece ter vindo do ALGOL 68, por exemplo, inglês:

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

  case month in
    31,
    if year mod 4=0  year mod 1000    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 da União Soviética fez o mesmo: em inglês, a declaração de caso reverente de Algol68 diz case ~ in ~ out ~ esac, em cirílico, isto diz выб ~ в ~ либо ~ быв.

Então, em 1975, os blocos de código de Algol68 foram emprestados por Edsger Dijkstra para sua Linguagem de Comando Guardada . por exemplo

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

Presumivelmente Dijstra usado "vigiado Blocks" para superar a outra oscilação ambigüidade implementado em Algol60 e então re-engenharia na Linguagem de Programação C . (cf. turno-reduzir conflito ) .

Finalmente - do Algol68 - " esac" chegou ao shell Bourne de 1977 (onde você descobriu esac), cortesia de Stephen R. Bourne, que havia desenvolvido um compilador Algol68 antigo chamado ALGOL 68C .

Famosamente, Stephen também usou esses mesmos Blocos Guardados 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 do software Landon Curt Noll e Larry Bassel encontraram o código macro.h de Steve em 1984 enquanto trabalhavam no grupo de portões Genix da National Semiconductor e lutavam para entender sua aplicação. Então Landon & Larry criou o Concurso Internacional de Código Ofuscado C ...

De 1984 até hoje, existem milhares de outras linguagens de programação "melhores" que não usam os Comandos Guardados de Dijkstra. E o uso deles por Steven Bourne macro.hagora é frequentemente citado nas "Dissertações de Desenvolvimento de Software" dos estudantes de TI como prova de que não dormiam em palestras. :-)

NevilleDNZ
fonte
O que é case out? nunca visto que a sintaxe
Dani_l
11
@Dani_l Essa é a sintaxe Algol68 não adotada pelo shell bourne.
Jlliagre
Por que eles chamariam isso, odmesmo que ainda não tivesse sido tirado? Não seria rofou elihw?
precisa saber é o seguinte
Escolher do ~ od, if ~ fie case ~ esacsignifica simplesmente que infinitas gerações futuras de estudantes de graduação será capaz de refletir Algol68 e adicionar um simples "crítica" de Algol68 em seu projeto final do ano, sem ter que escrever mais, em seguida, uma página (linha?) De código Algol68.
precisa saber é o seguinte
1

Sim, é necessário. Como Jacob aponta acima, a lógica é a mesma que if/ fi. Delimitadores tradicionais de comentários em C /*e */também emparelham da mesma forma. Como o C foi escrito para que o Unix pudesse ser escrito principalmente em C, com o mínimo de código de montagem, com uma grande sobreposição entre as equipes de desenvolvimento do C e do Unix, é razoável assumir uma fonte comum da noção de que o equivalente final de um multi O delimitador de bloco de caracteres deve ter a mesma sequência de caracteres na ordem inversa.

Em contraste, laços como for, whilee untiluso do... doneem vez de inverter ordem de caracteres, para que haja alguma inconsistência.

Monty Harder
fonte
3
A sintaxe veio de Bourne, que novamente foi inspirado pela ALGOL.
Runium 18/01/16