“ esac” หมายถึงอะไรในตอนท้ายของคำสั่ง bash case? จำเป็นหรือไม่


55

ฉันพบตัวอย่าง "esac" หลายรายการที่ท้ายคำสั่ง bash case แต่ฉันไม่พบเอกสารที่ชัดเจนเกี่ยวกับการใช้งาน หน้าคนใช้มันและยังมีดัชนีในคำว่า ( https://www.gnu.org/software/bash/manual/bashref.html#index-esac ) แต่ไม่ได้กำหนดให้ใช้ มันเป็นวิธีที่จำเป็นในการจบคำสั่งกรณีวิธีปฏิบัติที่ดีที่สุดหรือเทคนิคบริสุทธิ์


2
รายการดัชนีสำหรับesacคะแนนตรงตามที่ควร - ไปยังบรรทัดที่กำหนดและแสดงให้เห็นว่าจำเป็นต้องใช้
ฮอบส์

@ ฮอบส์คุณถูกต้องว่าดัชนีชี้ไปที่บรรทัดที่แสดงให้เห็นถึงการใช้งาน แต่ไม่ได้กำหนดไว้ในทางใดทางหนึ่งโดยเฉพาะอย่างยิ่งเมื่อเทียบกับวิธีที่อธิบายการใช้อักขระอื่นเช่น "|" หรือ ";" หรือ ";;". ตอนนี้ฉันได้อ่านคำตอบแล้วการสะกดคำ "case" ข้างหลังดูเหมือนจะเป็นมาตรฐานที่แท้จริงสำหรับคำสั่งสุดท้ายที่ผู้ใช้ที่มีประสบการณ์ส่วนใหญ่จะใช้เพื่อให้สิทธิ์
GrnMtnBuckeye

หากคุณไม่มีesacหรือชอบอะไรคุณคิดว่าจะสามารถบอกได้ว่าจุดสิ้นสุดของcaseคำสั่งนั้นอยู่ที่ไหน
Barmar

มันกำหนดว่ามันเป็นส่วนหนึ่งของไวยากรณ์ของcaseคำสั่งในลักษณะเดียวกับที่else, elifและfiมีการกำหนดไว้เป็นส่วนหนึ่งของไวยากรณ์ของifคำสั่ง มันไม่มีซีแมนทิกส์ของมันเองดังนั้นจึงไม่มีอะไรจะพูดเกี่ยวกับมัน แต่มันอยู่ท้ายคำจำกัดความของcaseคำแถลงดังนั้นมันจึงเป็นจุดcaseสิ้นสุดของคำแถลง ความจริงที่ว่ามันcaseสะกดไปทางด้านหลังนั้นเป็นความอยากรู้อยากเห็นที่สะดวกสบาย แต่คอมพิวเตอร์ไม่สนใจมันรู้แค่ว่ามันกำลังมองหาคำที่แน่นอน
ฮอบส์

1
@ ฮอบส์ "... ไม่มีอะไรจะพูดเกี่ยวกับมัน ... " แต่คุณเพียงแค่เขียนย่อหน้าเพื่ออธิบายว่าทำไมไม่มีอะไรจะพูดเกี่ยวกับมัน สิ่งสำคัญคือเพียงเข้าใจความตั้งใจของ "esac" นั่นเป็นเหตุผลที่คำถามนี้มีคำตอบตรงกับจำนวน upvotes ที่ยุติธรรม
Angelo

คำตอบ:


99

ชอบfiสำหรับifและdoneสำหรับfor, esacเป็นวิธีที่จำเป็นในการยุติcaseคำสั่ง

esacถูกcaseสะกดไปข้างหลังเหมือนfiถูกifสะกดไปข้างหลัง ผมไม่ทราบว่าทำไมโทเค็นสิ้นสุดบล็อกไม่ได้forrof


33
คุณหมายความว่าทำไมมันไม่odจบdoบล็อก? :)
ไวด์การ์ด

4
ลองนึกภาพว่าต้องพิมพ์\odทุกครั้งที่คุณต้องการใช้ยูทิลิตี้นั้น! ซึ่งหายาก แต่จุดของฉันยืน;)
คะแนน _

2
ดึงคุณออกจาก 666 คุณยินดีต้อนรับ: P และคำตอบที่ยอดเยี่ยม!
TheWanderer

12
@Wildcard มันfiและไม่ใช่nehtดังนั้นโดยการเปรียบเทียบมันจะเป็นrof(หรือelihw) และไม่ใช่od(เช่นกันแน่นอนว่าodมีการดำเนินการไปแล้ว) ... แต่บางทีนี่อาจเป็นการคาดหวังความสอดคล้องของตัวเองมากเกินไปจากหนึ่งในภาษาที่ไม่สอดคล้องกันมากที่สุด มี
zwol

1
ROTFL ไม่มีอะไรจะพูดอีก
Gerhard d.

55

esacคำหลักย่อมเป็นตัวคั่นที่จำเป็นในการยุติcaseคำสั่งในbashและเปลือกหอยที่ใช้มากที่สุดใน Unix / Linux ไม่รวมcshครอบครัว

เดิมบอร์นเชลล์ถูกสร้างขึ้นโดยสตีฟบอร์นที่ทำงานก่อนหน้านี้ในALGOL68 ภาษานี้คิดค้นเทคนิคคำที่กลับด้านเพื่อคั่นบล็อก

case/esac

if/fi

do/od

หลังไม่มากdo/odแต่do/doneใน Bourne และเชลล์ที่ได้รับทั้งหมดรวมถึงbashเพราะodมีอยู่แล้วเป็นคำสั่ง Unix ตั้งแต่เริ่มก่อตั้ง ( o ctal d ump )

โปรดทราบว่าdo/doneมีการแนะนำบล็อกการทำงานโดย the for, the whileหรือuntilคำแนะนำ for, whileและuntilไม่จำเป็นต้องถูกยกเลิกเป็นdoneก็เพียงพอแล้ว นั่นเป็นเหตุผลที่ไม่จำเป็นต้องมีสมมติฐานrofและelihwโทเค็น


6

" esac" ยุติการ "" ก่อนหน้านี้caseในรูปแบบ " รหัสบล็อก "

ใน Algol68 มีการใช้งานโดยทั่วไปลำดับอักขระย้อนกลับของคำสำคัญที่แนะนำจะใช้สำหรับการยกเลิกสิ่งที่แนบมาเช่น ( if ~ then ~ else ~ fi, case ~ in ~ out ~ esac, for ~ while ~ do ~ od ).

ฉันจะเรียกพวกเขาว่า "เตรียมพร้อมบล็อก" หลังจากEdsger Dijkstraของเขาและเตรียมพร้อมภาษาคำสั่ง

odคงจะไม่ได้ถูกนำมาใช้ในบอร์นเชลล์เพราะก่อนการดำรงอยู่ของระบบปฏิบัติการยูนิกซ์"od คำสั่ง"

ประวัติศาสตร์:

แนวคิด "Guarded Block" นั้นมาจาก ALGOL 68เช่นภาษาอังกฤษ:

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;

ของโซเวียตการดำเนิน Algol68 LGUก็ทำเช่นเดียวกัน: ในคำสั่งกรณีที่อ่อนภาษาอังกฤษ Algol68 อ่านcase ~ in ~ out ~ esacใน Cyrillic выб ~ в ~ либо ~ бывนี้อ่าน

จากนั้นในปี 1975 Algol68 รหัสบล็อกถูกยืมโดยEdsger Dijkstraเขาเตรียมพร้อมภาษาคำสั่ง เช่น

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

สันนิษฐาน Dijstra ใช้ "เตรียมพร้อมบล็อก" ที่จะเอาชนะDangling อื่นคลุมเครือดำเนินการในAlgol60แล้วการออกแบบใหม่ในภาษาซี (เปรียบเทียบความขัดแย้งลดกะ )

สุดท้าย - จาก Algol68 - " esac" ทำให้มันเป็น 1977 เปลือกบอร์น (ที่คุณค้นพบesac) มารยาทของสตีเฟ่นอาร์บอร์นที่ได้รับการพัฒนาคอมไพเลอร์ Algol68 ต้นเรียกว่าALGOL 68C

ชื่อเสียงสตีเฟ่นยังใช้ Guarded Blocks เดียวกันนี้ใน "ไฟล์ส่วนหัว C" ชื่อmacro.h

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

อัจฉริยะด้านซอฟต์แวร์ที่โดดเด่นLandon Curt NollและLarry Basselสะดุดกับรหัส macro.h ของ Steve ในปี 1984 ในขณะที่ใช้งานในกลุ่ม porting Genix ของ National Semiconductor และพยายามที่จะเข้าใจการใช้งาน ดังนั้น Landon & Larry จึงสร้างการประกวด C International Obfuscated C ...

ตั้งแต่ปี 1984 จนถึงปัจจุบันมีภาษาการเขียนโปรแกรม "ดีกว่า" อื่น ๆ อีกหลายพันภาษาที่ไม่ได้ใช้คำสั่ง Guarded ของ Dijkstra และการใช้งานของ Steven Bourne ในmacro.hตอนนี้มักถูกอ้างถึงใน "วิทยานิพนธ์การพัฒนาซอฟต์แวร์" ของนักศึกษาระดับปริญญาตรีด้านไอทีเพื่อพิสูจน์ว่าพวกเขาไม่ได้นอนในการบรรยาย :-)


อะไรนะcase out? ไม่เคยเห็นไวยากรณ์นั้น
Dani_l

1
@Dani_l นั่นคือไวยากรณ์ Algol68 ที่ไม่ได้นำมาใช้โดยเชลล์ bourne
jlliagre

ทำไมพวกเขาถึงเรียกมันว่าodแม้ว่ามันจะไม่ได้ถูกใช้ไปแล้ว มันจะไม่เป็นrofหรือelihw?
flarn2006

หยิบdo ~ od, if ~ fiและcase ~ esacก็หมายความว่าคนรุ่นอนาคตไม่มีที่สิ้นสุดของนักศึกษาระดับปริญญาตรีจะสามารถที่จะไตร่ตรอง Algol68 และเพิ่มง่าย "วิจารณ์" ของ Algol68 ในโครงการปีสุดท้ายของพวกเขาโดยไม่ต้องเขียนจริงมากขึ้นแล้วหน้า (บรรทัด?) ของรหัส Algol68
NevilleDNZ

1

ใช่มันเป็นสิ่งจำเป็น เป็นจุดจาค็อบออกไปตรรกะของมันเป็นเช่นเดียวกับ/if fiตัวคั่นความคิดเห็นดั้งเดิม C /*และ*/ยังจับคู่ในทำนองเดียวกัน เนื่องจาก C เขียนขึ้นเพื่อให้ Unix สามารถเขียนได้ส่วนใหญ่ใน C โดยมีรหัสแอสเซมบลีต่ำสุดโดยมีการทับซ้อนกันอย่างมากระหว่างทีมพัฒนา C และ Unix จึงมีเหตุผลที่จะถือว่าแหล่งข้อมูลทั่วไปของความคิดที่ว่า -character block delimiter ควรเป็นลำดับตัวอักษรเดียวกันในลำดับย้อนกลับ

ในทางตรงกันข้ามห่วงเหมือนfor, whileและuntilการใช้งานdo... doneแทนของการย้อนกลับเพื่อตัวละครจึงมีบางส่วนที่ไม่สอดคล้องกัน


3
ไวยากรณ์มาจาก Bourne ซึ่งได้รับแรงบันดาลใจจาก ALGOL อีกครั้ง
Runium
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.