Che cosa significa "esac" alla fine di un'istruzione case bash? È richiesto?


55

Ho trovato più esempi di "esac" che appare alla fine di un'istruzione case bash ma non ho trovato alcuna documentazione chiara sul suo utilizzo. La pagina man lo usa e ha persino un indice sulla parola ( https://www.gnu.org/software/bash/manual/bashref.html#index-esac ), ma non ne definisce l'uso. È il modo richiesto per terminare un'affermazione del caso, una migliore pratica o una tecnica pura?


2
La voce di indice esacindica i punti esattamente dove dovrebbe - alla linea che lo definisce e mostra che è richiesto.
Hobbs,

@hobbs, hai ragione che l'indice punta alla linea che ne illustra l'utilizzo ma non lo definisce in alcun modo, soprattutto rispetto al modo in cui descrive l'uso di altri caratteri come "|" o ";" o ";;". Ora che ho letto le risposte, il "caso" all'indietro sembra essere uno standard di fatto per terminare i comandi che la maggior parte degli utenti esperti lo darebbe per scontato.
GrnMtnBuckeye,

Se non hai avuto esaco qualcosa del genere, come pensi che sarebbe in grado di dire dove si trova la fine della casedichiarazione?
Barmar,

Si definisce come parte della sintassi della casedichiarazione, nello stesso modo in cui else, elife fisono definiti come parte della sintassi di una ifdichiarazione. Non ha una semantica propria, quindi non c'è nulla da dire al riguardo, ma è alla fine della definizione di caseun'istruzione, quindi è dove casefinisce un'istruzione. Il fatto che sia casescritto al contrario è una curiosità conveniente, ma al computer non importa, sa solo che sta cercando una certa parola.
Hobbs,

1
@hobbs "... non c'è niente da dire al riguardo ..." eppure hai appena scritto un paragrafo di spiegazione del perché non c'è nulla da dire al riguardo. L'importante è capire l'intento di "esac". Ecco perché questa domanda ha una risposta chiara con un discreto numero di voti.
Angelo,

Risposte:


99

Come fiper ife doneper for, esacè il modo richiesto per terminare caseun'istruzione.

esacè casescritto all'indietro, piuttosto come fiè ifscritto all'indietro. Non so perché il token che termina un forblocco non lo sia rof.


33
Intendi perché non odfinisce un doblocco? :)
Wildcard il

4
Immagina di dover digitare \odogni volta che vuoi usare quell'utilità! Il che è raro, ma il mio punto
vale

2
Ti ho tolto di 666. Prego: P. E ottima risposta!
TheWanderer,

12
@Wildcard È fie non neht, quindi per analogia sarebbe rof(o elihw) e non od(anche, ovviamente, odè già stato preso) ... ma forse questo si aspetta troppa autoconsistenza da uno dei linguaggi più incoerenti c'è.
zwol,

1
ROTFL nient'altro da dire
gerhard d.

55

La esacparola chiave è in effetti un delimitatore necessario per terminare caseun'istruzione bashe la maggior parte delle shell utilizzate su Unix / Linux esclude la cshfamiglia.

La shell Bourne originale è stata creata da Steve Bourne che in precedenza aveva lavorato su ALGOL68 . Questo linguaggio ha inventato questa tecnica inversa per delimitare i blocchi.

case/esac

if/fi

do/od

Quest'ultimo non è altro do/od, ma do/donea Bourne e tutte le conchiglie derivati tra cui bash, perché odera già esistente come un comando Unix sin dal suo inizio ( o ctal d UMP ).

Si noti che do/donei blocchi funzionali sono introdotte da ciascuna delle for, i while, o le untilistruzioni. for, whileE untilnon hanno bisogno di essere terminato come doneè sufficiente. Questo è il motivo per cui non è necessario l'ipotetico rofe i elihwtoken.


6

Il " esac" termina un precedente " case" per formare un " blocco di codice ".

In Algol68 vengono utilizzati, in genere la sequenza di caratteri invertiti della parola chiave introduttiva viene utilizzata per terminare il recinto, ad es. ( if ~ then ~ else ~ fi, case ~ in ~ out ~ esac, for ~ while ~ do ~ od ).

Li chiamerei "blocchi custoditi" come Edsger Dijkstra e il suo linguaggio di comando custodito .

odpresumibilmente non fu usato nella Bourne Shell a causa della preesistenza del comando "od" di Unix .

La storia:

L'idea di "Guarded Block" sembra provenire da ALGOL 68, ad esempio l'inglese:

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;

L' implementazione sovietica della LGU Algol68 ha fatto lo stesso: in inglese si legge la riverente dichiarazione del caso Algol68 case ~ in ~ out ~ esac, in cirillico si legge выб ~ в ~ либо ~ быв.

Poi nel 1975 i blocchi di codice di Algol68 furono presi in prestito da Edsger Dijkstra per il suo linguaggio di comando custodito . per esempio

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

Presumibilmente Dijstra utilizzato "Blocchi custodito" per superare l' altro penzoloni ambiguità implementato in Algol60 e poi riprogettato nel linguaggio di programmazione C . (cfr . conflitto di riduzione-riduzione ) .

Infine - da Algol68 - " esac" è arrivato alla shell Bourne del 1977 (dove hai scoperto esac) per gentile concessione di Stephen R. Bourne che aveva sviluppato un compilatore Algol68 chiamato ALGOL 68C .

Notoriamente Stephen ha anche usato questi stessi blocchi protetti in un "file di intestazione C" chiamato macro.h

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

I notevoli geni del software Landon Curt Noll e Larry Bassel si imbatterono nel codice macro.h di Steve nel 1984 mentre lavoravano nel gruppo porting Genix di National Semiconductor e facevano fatica a comprenderne l'applicazione. E così Landon & Larry hanno quindi creato il Concorso internazionale per codice C offuscato ...

Dal 1984 ad oggi ci sono state diverse migliaia di altri linguaggi di programmazione "migliori" che non usano i Comandi custoditi di Dijkstra. E il loro uso da parte di Steven Bourne macro.hè ora spesso citato nelle "Dissertazioni sullo sviluppo del software" degli studenti IT come prova del fatto che non dormivano durante le lezioni. :-)


Cosa case out? mai visto quella sintassi
Dani_l

1
@Dani_l Questa è la sintassi Algol68 non adottata dalla shell Bourne.
jlliagre,

Perché lo chiamerebbero odanche se non fosse già stato preso? Non sarebbe rofo elihw?
flarn2006,

Picking do ~ od, if ~ fie case ~ esacsignifica semplicemente che le future generazioni di infinite undergrads saranno in grado di riflettere Algol68 e aggiungere un semplice "critica" della Algol68 nel loro ultimo anno di progetto, senza dover effettivamente scrivere più di una pagina (la linea?) Del Codice Algol68.
NevilleDNZ,

1

Sì, è richiesto Come Jacob sottolinea sopra, la sua logica è la stessa di if/ fi. Delimitatori di commenti C tradizionali /*e */anche accoppiati in modo simile. Poiché C è stato scritto in modo che Unix potesse essere scritto principalmente in C, con il minimo del codice assembly, con una grande sovrapposizione tra i team di sviluppo C e Unix, è ragionevole supporre una fonte comune dell'idea che l'equivalente di chiusura di un multi -Il delimitatore del blocco di caratteri dovrebbe essere la stessa sequenza di caratteri in ordine inverso.

Al contrario, i loop gradiscono for, whilee untilusano do... doneinvece di invertire l'ordine dei personaggi, quindi c'è qualche incoerenza.


3
La sintassi proveniva da Bourne, che di nuovo è stato ispirato da ALGOL.
Runium,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.