¿Qué significa "esac" al final de una declaración de caso bash? ¿Se requiere?

55

He encontrado varios ejemplos de "esac" que aparecen al final de una declaración de caso bash, pero no he encontrado ninguna documentación clara sobre su uso. La página de manual lo usa e incluso tiene un índice en la palabra ( https://www.gnu.org/software/bash/manual/bashref.html#index-esac ), pero no define su uso. ¿Es la forma requerida de finalizar una declaración de caso, una mejor práctica o una técnica pura?

GrnMtnBuckeye
fuente
2
La entrada de índice para los esacpuntos exactamente donde debería, a la línea que lo define e ilustra que es obligatorio.
hobbs
@hobbs, tiene razón en que el índice apunta a la línea que ilustra su uso pero no lo define de ninguna manera, especialmente en comparación con la forma en que describe el uso de otros caracteres como "|" o ";" o ";;". Ahora que he leído la (s) respuesta (s), el "caso" de ortografía hacia atrás parece ser un estándar de facto para finalizar comandos que la mayoría de los usuarios experimentados darían por sentado.
GrnMtnBuckeye
Si no lo tuviera esaco algo así, ¿cómo cree que podría decir dónde está el final de la casedeclaración?
Barmar
Se define como siendo parte de la sintaxis de la caseinstrucción, de la misma manera que else, elify fise define como parte de la sintaxis de una ifdeclaración. No tiene semántica propia, por lo que no hay nada que decir al respecto, pero está al final de la definición de una casedeclaración, por lo que es donde casetermina una declaración. El hecho de que esté caseescrito al revés es una curiosidad conveniente, pero a la computadora no le importa, solo sabe que está buscando una palabra determinada.
hobbs
1
@hobbs "... no hay nada que decir al respecto ..." pero acabas de escribir un párrafo explicativo de por qué no hay nada que decir al respecto. Lo importante es entender la intención del "esac". Es por eso que esta pregunta tiene una respuesta directa con un buen número de votos a favor.
Angelo

Respuestas:

99

Me gusta fipor ify donepara for, esaces la forma requerida de finalizar una casedeclaración.

esacse casedeletrea hacia atrás, más bien como fise ifdeletrea hacia atrás. No sé por qué el token que termina un forbloque no lo es rof.

Jacob Minshall
fuente
33
¿Quieres decir por qué no es odpara terminar un dobloque? :)
Comodín el
44
¡Imagine tener que escribir \odcada vez que quiera usar esa utilidad! Lo cual es raro, pero mi punto es
válido
2
Te saqué del 666. De nada: P. Y gran respuesta!
TheWanderer
12
@Wildcard Es fiy no neht, así que por analogía sería rof(o elihw) y no od(también, por supuesto, odya está tomado) ... pero tal vez esto espere demasiada coherencia de uno de los lenguajes más inconsistentes Ahi esta.
zwol
1
ROTFL nada más que decir
gerhard d.
55

De hecho, la esacpalabra clave es un delimitador requerido para finalizar una casedeclaración bashy la mayoría de los shells utilizados en Unix / Linux, excluyendo la cshfamilia.

El shell Bourne original fue creado por Steve Bourne, quien trabajó anteriormente en ALGOL68 . Este lenguaje inventó esta técnica de palabra invertida para delimitar bloques.

case/esac

if/fi

do/od

Este último es no más do/od, pero do/doneen Bourne y todas las conchas derivados incluidos bashporque odya estaba vigente como un comando de Unix desde su creación ( o CTAL d UMP ).

Tenga en cuenta que los do/donebloques funcionales se introducen mediante las instrucciones the for, the whileo until. for, whiley untilno es necesario terminarlo, ya que donees suficiente. Esa es la razón por la cual no hay necesidad de los hipotéticos rofy los elihwtokens.

jlliagre
fuente
6

El " esac" termina un "anterior" casepara formar un " bloque de código ".

En Algol68 se usan, generalmente la secuencia de caracteres invertida de la palabra clave de introducción se usa para terminar el recinto, p. Ej. ( if ~ then ~ else ~ fi, case ~ in ~ out ~ esac, for ~ while ~ do ~ od ).

Los llamaría "Bloques guardados" después de Edsger Dijkstra y su lenguaje de comando guardado .

odpresumiblemente no se utilizó en Bourne Shell debido a la preexistencia del comando "od" de Unix .

La historia:

La idea del "bloque guardado" parece provenir de ALGOL 68, por ejemplo, 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;

La implementación de la LGU Algol68 del soviet hizo lo mismo: en inglés se lee la declaración de caso reveladora de Algol68 case ~ in ~ out ~ esac, en cirílico esto se lee выб ~ в ~ либо ~ быв.

Luego, en 1975, los bloques de código de Algol68 fueron prestados por Edsger Dijkstra para su Lenguaje de comando guardado . p.ej

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

Presumiblemente Dijstra utiliza "bloques" de vigilado para superar la persona que cuelga ambigüedad implementado en Algol60 y luego re-ingeniería en el lenguaje de programación C . (cf. desplazamiento-reducir conflicto ) .

Finalmente, de Algol68, " esac" llegó al shell Bourne de 1977 (donde descubrió esac) por cortesía de Stephen R. Bourne, quien había desarrollado un compilador de Algol68 temprano llamado ALGOL 68C .

El famoso Stephen también usó estos mismos bloques guardados en un "archivo de encabezado C" llamado macro.h

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

Los genios notables del software Landon Curt Noll y Larry Bassel se toparon con el código macro.h de Steve en 1984 mientras trabajaban en el grupo de transferencia Genix de National Semiconductor y lucharon por comprender su aplicación. Y entonces Landon & Larry crearon el Concurso Internacional de Código C Ofuscado ...

Desde 1984 hasta hoy ha habido varios miles de otros "mejores" lenguajes de programación que no utilizan los comandos guardados de Dijkstra. Y el uso de Steven Bourne en ellos macro.hahora se cita a menudo en las "Disertaciones de desarrollo de software" de estudiantes universitarios de TI como prueba de que no dormían en las conferencias. :-)

NevilleDNZ
fuente
¿Qué es case out? nunca he visto esa sintaxis
Dani_l
1
@Dani_l Esa es la sintaxis Algol68 no adoptada por el shell bourne.
jlliagre
¿Por qué lo llamarían odincluso si no lo hubieran tomado? ¿No sería rofo elihw?
flarn2006
Escoger do ~ od, if ~ fiy case ~ esacsimplemente significa que un sinfín de futuras generaciones de estudiantes podrán reflexionar sobre Algol68 y agregar una simple "crítica" de Algol68 en su proyecto de último año, sin tener que escribir más de una página (¿línea?) De código Algol68.
NevilleDNZ
1

Sí, es obligatorio Como Jacob señala arriba, la lógica es la misma que if/ fi. Delimitadores de comentarios C tradicionales /*y */también se emparejan de manera similar. Debido a que C se escribió para que Unix se pudiera escribir principalmente en C, con el mínimo de código de ensamblaje, con una gran superposición entre los equipos de desarrollo de C y Unix, es razonable asumir una fuente común de la noción de que el equivalente de cierre de un multi El delimitador de bloque de caracteres debe ser la misma secuencia de caracteres en orden inverso.

Por el contrario, los bucles tienen gusto de for, whiley untilusan do... en donelugar de invertir el orden de los caracteres, por lo que hay alguna inconsistencia.

Monty Harder
fuente
3
La sintaxis vino de Bourne, que nuevamente fue inspirada por ALGOL.
Runium