Was bedeutet "esac" am Ende einer Bash-Case-Anweisung? Ist es erforderlich?

55

Ich habe mehrere Beispiele für "esac" gefunden, die am Ende einer Bash-Case-Anweisung erscheinen, aber ich habe keine eindeutige Dokumentation zu ihrer Verwendung gefunden. Die Manpage verwendet es und hat sogar einen Index für das Wort ( https://www.gnu.org/software/bash/manual/bashref.html#index-esac ), definiert aber nicht seine Verwendung. Ist dies der erforderliche Weg, um eine Fallbeschreibung, eine bewährte Vorgehensweise oder eine reine Technik zu beenden?

GrnMtnBuckeye
quelle
2
Der Indexeintrag für esacPunkte genau dort, wo er sein sollte - auf die Linie, die ihn definiert und veranschaulicht, dass er erforderlich ist.
Hobbs
@hobbs, Sie haben Recht, dass der Index auf die Zeile zeigt, die seine Verwendung veranschaulicht, aber ihn in keiner Weise definiert, insbesondere im Vergleich zu der Art, wie er die Verwendung anderer Zeichen wie "|" beschreibt. oder ";" oder ";;". Nachdem ich die Antwort (en) gelesen habe, scheint die Schreibweise "case" (Groß- / Kleinschreibung) in umgekehrter Reihenfolge ein De-facto-Standard für das Beenden von Befehlen zu sein, den erfahrene Benutzer für selbstverständlich halten würden.
GrnMtnBuckeye
Wenn Sie es nicht hätten esacoder so ähnlich, wie könnte es Ihrer Meinung nach erkennen, wo das Ende der caseAussage liegt?
Barmar
Es definiert sie als Teil der Syntax des Wesens caseAnweisung, in der gleichen Weise, else, elif, und fidefiniert sind als Teil der Syntax eines sein ifAussage. Es hat keine eigene Semantik, daher gibt es nichts zu sagen, aber es steht am Ende der Definition einer caseAnweisung, also caseendet eine Anweisung. Die Tatsache, dass es caserückwärts geschrieben ist, ist eine praktische Kuriosität, aber dem Computer ist es egal, er weiß nur, dass er nach einem bestimmten Wort sucht.
Hobbs
1
@hobbs "... dazu gibt es nichts zu sagen ..." Sie haben jedoch nur einen Abschnitt mit Erläuterungen dazu geschrieben, warum dazu nichts zu sagen ist. Das Wichtigste ist, nur die Absicht des "esac" zu verstehen. Deshalb hat diese Frage eine klare Antwort mit einer angemessenen Anzahl von positiven Stimmen.
Angelo

Antworten:

99

Wie fifür ifund donefür for, esacist der erforderliche Weg, um eine caseAussage zu beenden .

esacist caserückwärts buchstabiert, eher wie fiist ifrückwärts buchstabiert. Ich weiß nicht, warum das Token, das einen forBlock beendet, nicht ist rof.

Jacob Minshall
quelle
33
Du meinst, warum ist es nicht so od, einen doBlock zu beenden ? :)
Wildcard
4
Stellen Sie sich vor, Sie müssten \odjedes Mal tippen, wenn Sie dieses Dienstprogramm verwenden möchten! Was selten ist, aber mein Punkt steht;)
Score_Under
2
Hat dich von 666 abgezogen. Gern geschehen: P. Und tolle Antwort!
TheWanderer
12
@Wildcard Es ist fiund nicht neht, also wäre es analog rof(oder elihw) und nicht od(natürlich odist es auch schon vergeben) ... aber vielleicht erwartet dies zu viel Selbstkonsistenz aus einer der selbstinkonsistentesten Sprachen es gibt.
zwol
1
ROTFL sonst nichts zu sagen
gerhard d.
55

Das esacSchlüsselwort ist in der Tat ein erforderliches Trennzeichen, um eine caseAnweisung zu beenden, bashund die meisten unter Unix / Linux verwendeten Shells mit Ausnahme der cshFamilie.

Die ursprüngliche Bourne-Shell wurde von Steve Bourne erstellt, der zuvor an ALGOL68 gearbeitet hatte . Diese Sprache erfand diese umgekehrte Worttechnik, um Blöcke abzugrenzen.

case/esac

if/fi

do/od

Letzteres gibt es do/odnur do/donein Bourne und allen abgeleiteten Shells, auch bashweil odes seit seiner Einführung ( o ctal d ump ) bereits als Unix-Befehl existierte .

Beachten Sie, dass do/doneFunktionsblöcke entweder durch die for, die whileoder die untilAnweisungen eingeführt werden. for, whileUnd untilmüssen nicht beendet werden als doneausreichend ist. Das ist der Grund, warum das Hypothetische rofund die elihwToken nicht benötigt werden .

jlliagre
quelle
6

Das " esac" beendet ein früheres " case", um einen " Codeblock " zu bilden.

In Algol68 werden sie verwendet, im Allgemeinen wird die umgekehrte Zeichenfolge des einleitenden Schlüsselworts zum Beenden des Gehäuses verwendet, z ( if ~ then ~ else ~ fi, case ~ in ~ out ~ esac, for ~ while ~ do ~ od ).

Ich würde sie nach Edsger Dijkstra und seiner Guarded Command Language "Guarded Blocks" nennen .

odWurde in der Bourne-Shell vermutlich nicht verwendet, da der Unix- Befehl "od" bereits vorhanden war .

Die Geschichte:

Die Idee "Guarded Block" scheint von ALGOL 68 zu stammen, zB Englisch:

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;

Die Algol68-LGU-Implementierung des Sowjets hat das Gleiche getan: In Englisch lautet die ehrfurchtsvolle Erklärung von Algol68 case ~ in ~ out ~ esac, in Kyrillisch lautet sie выб ~ в ~ либо ~ быв.

1975 wurden die Code-Blöcke von Algol68 von Edsger Dijkstra für seine Guarded Command Language ausgeliehen . z.B

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

Vermutlich verwendete Dijstra "Guarded Blocks", um die in Algol60 implementierte und dann in der Programmiersprache C überarbeitete Dangling else- Ambiguität zu überwinden . (vgl. Schichtreduzierungskonflikt. )

Schließlich - von Algol68 - " esac" schaffte es 1977 mit freundlicher Genehmigung von Stephen R. Bourne , der einen frühen Algol68-Compiler namens ALGOL 68C entwickelt hatte, in die Bourne-Shell (wo Sie es entdeckten esac) .

Bekanntermaßen verwendete Stephen diese Guarded Blocks auch in einer "C-Header-Datei" namens " macro.h"

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

Die bemerkenswerten Software-Genies Landon Curt Noll und Larry Bassel stießen 1984 bei der Genix-Portierungsgruppe von National Semiconductor auf Steves macro.h-Code und hatten Mühe, dessen Anwendung zu verstehen. Und so gründete Landon & Larry den International Obfuscated C Code Contest ...

Von 1984 bis heute gab es mehrere tausend andere "bessere" Programmiersprachen, die die geschützten Befehle von Dijkstra nicht verwenden. Und Steven Bournes Einsatz in diesen macro.hStudiengängen wird inzwischen häufig in den "Software Development Dissertations" von IT-Studenten als Beweis dafür angeführt, dass sie nicht in Vorlesungen geschlafen haben. :-)

NevilleDNZ
quelle
Was ist case out?
Ich
1
@Dani_l Das ist die Algol68-Syntax, die von der Borowski-Shell nicht übernommen wird.
Juli
Warum sollten sie es nennen, odauch wenn es nicht schon vergeben war? Wäre es nicht rofoder elihw?
Flarn2006
Picking do ~ od, if ~ fiund case ~ esaceinfach bedeutet , dass endlose künftige Generationen von undergrads der Lage sein werden Algol68 nachzudenken und eine einfache „Kritik“ von Algol68 in ihrem letztes Jahr Projekt hinzufügen, ohne tatsächlich mehr schreiben , um mit dann einer Seite (Linie?) Von Algol68 Code.
NevilleDNZ
1

Ja, das ist erforderlich. Wie Jacob oben ausgeführt hat, ist die Logik dieselbe wie bei if/ fi. Herkömmliche C-Kommentar-Begrenzer /*und werden */ähnlich gepaart. Da C so geschrieben wurde, dass Unix größtenteils in C mit einem Minimum an Assembler-Code und einer großen Überlappung zwischen den C- und Unix-Entwicklungsteams geschrieben werden kann, ist es vernünftig, eine gemeinsame Quelle des Begriffs anzunehmen, dass das abschließende Äquivalent eines Multi -Zeichenblock-Begrenzer sollte dieselbe Zeichenfolge in umgekehrter Reihenfolge sein.

Im Gegensatz dazu Schleifen wie for, whileund untilVerwendung do... donestattdessen Charakter , um umzukehren, so gibt es einige Inkonsistenz.

Monty Harder
quelle
3
Syntax kam von Bourne, das wiederum von ALGOL inspiriert war.
Runium