Que signifie "esac" à la fin d'une déclaration de cas bash? Est-ce nécessaire?

56

J'ai trouvé plusieurs exemples de "esac" apparaissant à la fin d'une déclaration de cas bash mais je n'ai trouvé aucune documentation claire sur son utilisation. La page de manuel l'utilise et a même un index sur le mot ( https://www.gnu.org/software/bash/manual/bashref.html#index-esac ), mais ne définit pas son utilisation. Est-ce le moyen requis pour mettre fin à une déclaration de cas, à une pratique exemplaire ou à une technique pure?

GrnMtnBuckeye
la source
2
L'entrée d'index pour les esacpoints exactement où elle devrait - à la ligne qui la définit et illustre que c'est nécessaire.
Hobbs
@hobbs, vous avez raison de dire que l'index pointe sur la ligne qui illustre son utilisation, mais il ne le définit en aucune manière, surtout par rapport à la façon dont il décrit l'utilisation d'autres caractères comme "|" ou ";" ou ";;". Maintenant que j'ai lu la ou les réponses, le "cas" de l'orthographe en arrière semble être un tel standard de facto pour mettre fin aux commandes que les utilisateurs les plus expérimentés le prendraient pour acquis.
GrnMtnBuckeye
Si vous n'en aviez pas esacou quelque chose du genre, comment pensez-vous qu'il serait capable de dire où se trouve la fin de la casedéclaration?
Barmar
Elle définit comme faisant partie de la syntaxe de la casedéclaration, de la même manière que else, elifet fisont définies comme faisant partie de la syntaxe d'une ifdéclaration. Il n'a pas de sémantique propre, donc il n'y a rien à dire à ce sujet, mais c'est à la fin de la définition d'une casedéclaration, donc c'est là que casese termine une déclaration. Le fait qu'il soit caseorthographié à l'envers est une curiosité commode, mais l'ordinateur ne s'en soucie pas, il sait simplement qu'il recherche un mot particulier.
Hobbs
1
@ Hobbs "... il n'y a rien à dire à ce sujet ..." mais vous venez d'écrire un paragraphe d'explication expliquant pourquoi rien à dire à ce sujet. L'important est simplement de comprendre l'intention de "l'esac". C'est pourquoi cette question a une réponse directe avec un bon nombre de votes positifs.
Angelo

Réponses:

100

Comme fipour ifet donepour for, esacest le moyen requis pour terminer une casedéclaration.

esacest caseorthographié en arrière, un peu comme fiest iforthographié en arrière. Je ne sais pas pourquoi le jeton qui termine un forbloc ne l'est pas rof.

Jacob Minshall
la source
34
Vous voulez dire, pourquoi ne pas odmettre fin à un dobloc? :)
Wildcard
4
Imaginez avoir à taper \odchaque fois que vous voulez utiliser cet utilitaire! Ce qui est rare, mais mon argument est
valable
2
Vous avez tiré de 666. De rien: P. Et bonne réponse!
TheWanderer
12
@Wildcard C'est fiet pas neht, donc par analogie ce serait rof(ou elihw) et pas od(aussi, bien sûr, odc'est déjà pris) ... mais peut-être attendons-nous trop de cohérence de l'un des langages les plus contradictoires il y a.
dimanche
1
ROTFL rien d'autre à dire
gerhard d.
55

Le esacmot clé est en effet un délimiteur obligatoire pour terminer une caseinstruction bashet la plupart des shells utilisés sous Unix / Linux, à l'exclusion de la cshfamille.

Le shell Bourne original a été créé par Steve Bourne qui avait auparavant travaillé sur ALGOL68 . Ce langage a inventé cette technique de mots inversés pour délimiter des blocs.

case/esac

if/fi

do/od

Ce dernier est plus , do/odmais do/donedans Bourne et toutes les coquilles dérivées , y compris bashparce que oddéjà existant comme une commande Unix depuis sa création ( o CTAL d ump ).

Notez que do/doneles blocs fonctionnels sont introduits par le for, le whileou les untilinstructions. for, whileEt untilne pas être résiliées comme doneest suffisante. C'est la raison pour laquelle il n'est pas nécessaire d'utiliser l'hypothèse rofet les elihwjetons.

jlliagre
la source
6

Le " esac" termine un " case" antérieur pour former un " bloc de code ".

Dans Algol68, ils sont utilisés, généralement la séquence de caractères inversée du mot-clé d'introduction est utilisée pour terminer l'enceinte, par exemple: ( if ~ then ~ else ~ fi, case ~ in ~ out ~ esac, for ~ while ~ do ~ od ).

Je les appellerais "blocs gardés" après Edsger Dijkstra et son langage de commande gardé .

odprobablement pas été utilisé dans Bourne Shell à cause de la pré-existence de la commande Unix "od" .

L'histoire:

L’idée "Guarded Block" semble provenir d’ ALGOL 68, par exemple en anglais:

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 mise en œuvre de la LGU Algol68 du Soviet a fait de même: en anglais, la déclaration de cas respectueuse d’Algol68 est lue case ~ in ~ out ~ esac, celle en cyrillique выб ~ в ~ либо ~ быв.

Puis, en 1975, Edsger Dijkstra a emprunté les blocs de code d'Algol68 pour son Guarded Command Language . par exemple

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

On peut supposer que Dijstra utilisé « blocs » Surveillé pour surmonter la Dangling autre ambiguïté mis en œuvre dans Algol60 puis réorganisées dans le C Langage de programmation . (cf. shift-réduire le conflit. )

Enfin - d’Algol68 - " esac" a été intégré dans le shell Bourne de 1977 (où vous l’avez découvert esac) grâce à Stephen R. Bourne qui avait mis au point un ancien compilateur Algol68 appelé ALGOL 68C .

Stephen a aussi utilisé ces mêmes blocs protégés dans un "fichier d'en-tête C" appelé macro.h

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

Les génies logiciels réputés Landon Curt Noll et Larry Bassel sont tombés par hasard sur le code macro.h de Steve en 1984 alors qu’ils travaillaient pour le groupe de portage Genix de National Semiconductor et avaient du mal à comprendre son application. Landon & Larry ont alors créé le concours international de code C obscurci ...

De 1984 à nos jours, plusieurs milliers d' autres "meilleurs" langages de programmation n'utilisant pas les commandes gardées de Dijkstra. Et leur utilisation par Steven Bourne macro.hest à présent souvent citée dans les "Dissertations sur le développement logiciel" des étudiants en informatique comme la preuve qu'ils n'étaient pas endormis dans des cours magistraux. :-)

NevilleDNZ
la source
C'est quoi case out? jamais vu cette syntaxe
Dani_l
1
@Dani_l C'est la syntaxe Algol68 qui n'a pas été adoptée par le shell Bourne.
jeudi
Pourquoi l'appelleraient-ils odmême si ce n'était pas déjà pris? Ne serait-ce pas rofou elihw?
Flarn2006
La cueillette do ~ od, if ~ fiet case ~ esacsignifie simplement que les générations futures sans fin de undergrads seront en mesure de réfléchir Algol68 et ajouter un simple « critique » de Algol68 dans leur projet de fin d'année, sans avoir à réellement écrire plus de une page (ligne?) Du Code Algol68.
NevilleDNZ
1

Oui, c'est nécessaire. Comme Jacob le souligne ci-dessus, la logique est la même que if/ fi. Les délimiteurs de commentaires traditionnels en C /*et les */paires similaires. Parce que C a été écrit pour qu'Unix puisse être écrit principalement en C, avec le minimum de code assembleur, avec un grand chevauchement entre les équipes de développement C et Unix, il est raisonnable de supposer une source commune de la notion que l'équivalent final d'un multi le délimiteur de bloc de caractère doit être la même séquence de caractères dans l'ordre inverse.

En revanche, les boucles aiment for, whileet untilutilisent do... doneau lieu d'inverser l'ordre des caractères, il y a donc une certaine incohérence.

Monty Harder
la source
3
Syntax est venu de Bourne, qui a de nouveau été inspiré par ALGOL.
Runium