Không có nghĩa là gì es es Cảnh ở cuối của một tuyên bố trường hợp bash? Có cần thiết không?


55

Tôi đã tìm thấy nhiều ví dụ về "esac" xuất hiện ở phần cuối của một tuyên bố trường hợp bash nhưng tôi không tìm thấy bất kỳ tài liệu rõ ràng nào về việc sử dụng nó. Trang man sử dụng nó và thậm chí có một chỉ mục trên từ ( https://www.gnu.org/software/bash/manual/bashref.html#index-esac ), nhưng không xác định nó sử dụng. Đây có phải là cách bắt buộc để kết thúc một tuyên bố trường hợp, thực hành tốt nhất hoặc kỹ thuật thuần túy?


2
Mục nhập chỉ mục cho esaccác điểm chính xác nơi cần đến - đến dòng xác định nó và minh họa rằng nó bắt buộc.
hobbs

@hobbs, bạn đúng là chỉ mục trỏ đến dòng minh họa việc sử dụng nó nhưng nó không định nghĩa nó theo bất kỳ cách nào, đặc biệt là so với cách nó mô tả việc sử dụng các ký tự khác như "|" hoặc là ";" hoặc là ";;". Bây giờ tôi đã đọc (các) câu trả lời, "trường hợp" đánh vần ngược dường như là một tiêu chuẩn thực tế để kết thúc các lệnh mà hầu hết người dùng có kinh nghiệm sẽ coi đó là điều hiển nhiên.
GrnMtnBuckeye

Nếu bạn không có esachoặc một cái gì đó giống như vậy, làm thế nào bạn nghĩ rằng nó sẽ có thể cho biết nơi kết thúc của casetuyên bố là ở đâu?
Barmar

Nó định nghĩa nó như là một phần của cú pháp của casecâu lệnh, trong cùng một cách mà else, eliffiđược định nghĩa như là một phần của cú pháp của một iftuyên bố. Nó không có bất kỳ ngữ nghĩa nào của riêng nó, vì vậy không có gì để nói về nó, nhưng nó ở cuối định nghĩa của một casetuyên bố, vì vậy đó là nơi một casetuyên bố kết thúc. Thực tế là nó caseđánh vần ngược là một sự tò mò tiện lợi, nhưng máy tính không quan tâm, nó chỉ biết rằng nó đang tìm kiếm một từ nào đó.
hobbs

1
@hobbs "... không có gì để nói về nó cả ..." nhưng bạn vừa viết một đoạn giải thích về lý do tại sao không có gì để nói về nó. Điều quan trọng là chỉ cần hiểu ý định của "esac". Đó là lý do tại sao câu hỏi này có một câu trả lời thẳng thắn với số lượng upvote khá.
Angelo

Câu trả lời:


99

Giống như ficho ifdonecho for, esaclà cách bắt buộc để kết thúc một casetuyên bố.

esacđược caseđánh vần ngược, giống như fiđược ifđánh vần ngược. Tôi không biết tại sao mã thông báo kết thúc một forkhối lại không rof.


33
Ý bạn là tại sao nó không odkết thúc một dokhối? :)
tự đại diện

4
Hãy tưởng tượng bạn phải gõ \odmỗi lần bạn muốn sử dụng tiện ích đó! Điều này là hiếm, nhưng quan điểm của tôi là;)
Score_Under

2
Kéo bạn ra khỏi 666. Bạn được chào đón: P. Và câu trả lời tuyệt vời!
TheWanderer

12
@Wildcard Đó là fivà không neht, do đó, tương tự, nó sẽ là rof(hoặc elihw) và không od(tất nhiên, odcũng đã được sử dụng) ... nhưng có lẽ điều này đang mong đợi quá nhiều sự tự nhất quán từ một trong những ngôn ngữ không nhất quán nhất có.
zwol

1
ROTFL không có gì khác để nói
gerhard d.

55

Các esactừ khóa thực sự là một dấu phân cách cần thiết để chấm dứt một casetuyên bố trong bashvà hầu hết vỏ được sử dụng trên Unix / Linux không bao gồm cshgia đình.

Vỏ Bourne ban đầu được tạo ra bởi Steve Bourne , người trước đây đã làm việc trên ALGOL68 . Ngôn ngữ này đã phát minh ra kỹ thuật từ đảo ngược này để phân định các khối.

case/esac

if/fi

do/od

Loại thứ hai là không còn nữa do/odnhưng do/donetrong Bourne và tất cả các vỏ có nguồn gốc bao gồm bashodđã đã tồn tại như một lệnh Unix kể từ khi thành lập ( o ctal d UMP ).

Lưu ý rằng do/donecác khối chức năng được giới thiệu bởi một trong hai forthì while, hoặc untilhướng dẫn. for, whileuntilkhông cần phải được chấm dứt như donelà đủ. Đó là lý do tại sao không cần giả thuyết rofelihwmã thông báo.


6

" esac" Chấm dứt "" trước đó caseđể tạo thành một " khối mã ".

Trong Algol68, chúng được sử dụng, nói chung, chuỗi ký tự đảo ngược của từ khóa giới thiệu được sử dụng để chấm dứt bao vây, ví dụ: ( if ~ then ~ else ~ fi, case ~ in ~ out ~ esac, for ~ while ~ do ~ od ).

Tôi sẽ gọi chúng là "Khối bảo vệ" sau Edsger DijkstraNgôn ngữ chỉ huy được bảo vệ của anh ta .

odcó lẽ đã không được sử dụng trong Bourne Shell vì sự tồn tại của lệnh "od" Unix .

Lịch sử:

Ý tưởng "Khối bảo vệ" dường như xuất phát từ ALGOL 68, ví dụ tiếng Anh:

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;

Việc thực hiện Algol68 LGU của Liên Xô cũng làm như vậy: Trong tiếng Anh, tuyên bố về trường hợp tôn kính của tiếng Anh Algol68 case ~ in ~ out ~ esac, trong Cyrillic, điều này đọc выб ~ в ~ либо ~ быв.

Sau đó, vào năm 1975, các khối mã của Algol68 đã được Edsger Dijkstra mượn cho Ngôn ngữ chỉ huy được bảo vệ của ông . ví dụ

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

Có lẽ Dijstra sử dụng "gác Blocks" để vượt qua những khác Dangling nhập nhằng thực hiện trong Algol60 và sau đó tái chế trong các ngôn ngữ lập trình C . (xem xung đột giảm ca. )

Cuối cùng - từ Algol68 - " esac" đã biến nó thành vỏ Bourne năm 1977 (nơi bạn phát hiện ra esac) nhờ sự giúp đỡ của Stephen R. Bourne , người đã phát triển một trình biên dịch Algol68 đầu tiên có tên ALGOL 68C .

Nổi tiếng Stephen cũng đã sử dụng các Khối bảo vệ tương tự này trong "tệp tiêu đề C" có tên macro.h

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

Các thiên tài phần mềm đáng chú ý Landon Curt NollLarry Bassel tình cờ tìm thấy mã macro.h của Steve vào năm 1984 trong khi làm việc tại nhóm chuyển đổi Genix của National S bán dẫn và đấu tranh để hiểu ứng dụng của nó. Và thế là Landon & Larry sau đó đã tạo ra Cuộc thi mã C bị xáo trộn quốc tế ...

Từ năm 1984 cho đến ngày nay, đã có hàng ngàn ngôn ngữ lập trình "tốt hơn" khác không sử dụng Lệnh bảo vệ của Dijkstra. Và việc sử dụng chúng của Steven Bourne macro.hhiện nay thường được trích dẫn trong "Luận án phát triển phần mềm" của sinh viên đại học CNTT là bằng chứng cho thấy họ không ngủ trong các bài giảng. :-)


Có gì case out? chưa bao giờ thấy cú pháp đó
Dani_l

1
@Dani_l Đó là cú pháp Algol68 không được chấp nhận bởi trình bao bourne.
jlliagre

Tại sao họ gọi nó odngay cả khi nó chưa được thực hiện? Nó sẽ không rofhay elihw?
flarn2006

Chọn do ~ od, if ~ ficase ~ esacđơn giản có nghĩa là các thế hệ sinh viên vô tận trong tương lai sẽ có thể suy ngẫm về Algol68 và thêm một "phê bình" đơn giản về Algol68 vào dự án năm cuối của họ, mà không cần phải viết thêm một trang (dòng?) Của mã Algol68.
NevilleDNZ

1

Vâng, nó là bắt buộc. Như Jacob chỉ ra ở trên, logic của nó giống như if/ fi. Phân định bình luận C truyền thống /**/cũng cặp tương tự. Bởi vì C được viết sao cho Unix có thể được viết chủ yếu bằng C, với tối thiểu mã lắp ráp, với sự chồng chéo lớn giữa các nhóm phát triển C và Unix, nên có lý khi cho rằng một nguồn chung của khái niệm rằng tương đương đóng của đa Dấu phân cách khối -character phải là cùng một chuỗi các ký tự theo thứ tự ngược lại.

Ngược lại, các vòng lặp như for, whileuntilsử dụng do... donethay vì đảo ngược thứ tự ký tự, do đó có một số điểm không nhất quán.


3
Cú pháp đến từ Bourne, một lần nữa được lấy cảm hứng từ ALGOL.
Runium
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.