Là `if` và` then` thực sự là các chương trình


15

Tôi đã đọc rằng dấu chấm phẩy được sử dụng để phân tách các chương trình:

$ echo 3; ls -la

Có nghĩa là if, thenelsecác chương trình riêng biệt ở đây?

$ if [ $VARIABLE == abcdef ] ; then echo yes ; else echo no ; fi

Câu hỏi này không phải là về dấu chấm phẩy.



1
@StephenRauch Không thực sự là một bản sao. Thêm nữa đó là kết quả hợp lý từ Q đó, như một nỗ lực để hiểu thêm.
Spellweaver Gypsy

Công thức chương trình-y khác:[ $variable == abcdef ] && echo yes || echo no
Hagen von Eitzen

2
@HagenvonEitzen không hoàn toàn tương đương, nếu tuyên bố trong nhánh đầu tiên thất bại, lần thứ hai cũng sẽ thực thi.
Morgen

Câu trả lời:


26

Các ;tuyên bố tách (nói một cách lỏng lẻo). Nó (hầu như) luôn luôn có thể thay thế ;bằng một dòng mới.

Do đó, để ;phân tách hai chương trình, do đó ifthenphải là "chương trình" thì hơi đơn giản vì một câu lệnh có thể được tạo từ các từ dành riêng, hàm shell, tiện ích tích hợp và tiện ích bên ngoài, và kết hợp các chương trình này bằng cách sử dụng các toán tử ống và boolean, v.v. . Vân vân.

Cả hai ifthenlà những từ dành riêng trong ngữ pháp shell , không phải là "chương trình". Ở đây, chúng được sử dụng để xây dựng cái gọi là lệnh ghép .

echocó khả năng là một tiện ích tích hợp trong trình bao (nhưng không cần phải có) và lscó lẽ là một tiện ích bên ngoài (hoặc "chương trình" như bạn nói).


7

Mặc dù đó là một xấp xỉ đầu tiên công bằng khi người ta bắt đầu học những điều cơ bản của việc sử dụng shell, ở cấp độ "đây là cách người ta chạy một chương trình" và "đây là cách người ta chạy nhiều chương trình lần lượt trên một dòng" , nó không thực sự đúng.

Khó nắm bắt hơn đối với người mới bắt đầu nhưng giải thích chính xác hơn là ngôn ngữ shell là ngôn ngữ máy tính . Nó có một cú pháp . Cú pháp đó bao gồm các yếu tố từ vựng khác nhau bao gồm (trong số những thứ khác) dòng mới, toán tử, từ và từ dành riêng.

if, then, else, Và fiđều là những từ dành riêng . Chúng có ý nghĩa đặc biệt khi phân tích cú pháp đầu vào mà người ta đưa ra cho một vỏ, theo ngữ pháp của nó . Tương tự, ;là một toán tử phân tách .

Do đó, đầu vào trong ngôn ngữ shell được lấy toàn bộ, một chương trình máy tính được diễn giải bởi một chương trình khác, một trình thông dịch , shell. Phần ngữ pháp cá nhân của nó không phải là chương trình. Ngôn ngữ shell là một cách chỉ định các chương trình (khác) để shell chạy.

[không phải là một yếu tố từ vựng đặc biệt trong ngữ pháp shell như toán tử. Đó là một từ thông thường , đặt tên một chương trình như vậy được đặt tên [. Nhiều vỏ có một built-in phiên bản của chương trình này, kết hợp vào mã của chương trình bao chính nó, nhưng bạn cũng có thể tìm thấy một bên ngoài chương trình theo tên này ở đâu đó như /bin/[hoặc /usr/bin/[, mà các chương trình khác ngoài vỏ có thể gọi. Tương tự, ]không phải là một yếu tố từ vựng vỏ đặc biệt. Đó là một từ thông thường, trở thành một đối số cho [chương trình. Các [chương trình đòi hỏi tranh luận cuối cùng của nó, khi nó được thực thi, được ], mà nó tiến hành sau đó bỏ qua.

Một chương trình tương tự có tên trong câu hỏi của bạn là echo. Một lần nữa, hầu hết các shell đều có phiên bản tích hợp của chương trình này. Nhưng một lần nữa, cũng có một phiên bản bên ngoài của chương trình, ở đâu đó như /bin/echohoặc /usr/bin/echo, cho các chương trình không phải là shell để gọi.

Một chương trình thứ ba có tên trong câu hỏi của bạn là ls. Shell thường không có các phiên bản dựng sẵn của chương trình này và nó là một chương trình bên ngoài, được tìm thấy ở đâu đó như /bin/lshoặc /usr/bin/ls.

Đối với shell Bourne Again, bạn có thể đọc thêm về điều này trong Tính năng Shell cơ bản của tài liệu thông tin shell GNU Bourne Again. Các vỏ khác có ngữ pháp khác nhau, tự nhiên. Các đơn Unix Specification mô tả một cú pháp mà tất cả vỏ POSIX-tuân thủ QTI (trong chế độ POSIX-tuân thủ QTI của họ) có nghĩa vụ phải tuân theo.

đọc thêm

  • " Ngữ pháp Shell ". Ngôn ngữ lệnh Shell . Thông số kỹ thuật cơ sở Vấn đề 7. Nhóm mở. IEEE 1003.1-2008. SỐ 1937218812.
  • test. Tiện ích . Thông số kỹ thuật cơ sở Vấn đề 7. Nhóm mở. IEEE 1003.1-2008. SỐ 1937218812.
  • " Ngữ pháp Shell ". Hướng dẫn sử dụng Z Shell . phiên bản 5.3.1. 2017.

5

Nó thực sự không phải là quá xa vời để nghĩ về if, thenelsenhư các chương trình bên ngoài. Trên thực tế, lớp vỏ của Thompson trong phiên bản đầu tiên Unix được triển khai ifgotonhư các chương trình bên ngoài. Điều này là có thể bởi vì quy trình con chia sẻ các mô tả tệp với quy trình shell, do đó, một goto (chuyển tiếp) chỉ cần đọc đầu vào cho đến khi tìm thấy nhãn đích và sau đó thoát ra. Xem vỏ Thompson .


Hoặc thực sự thấy Laurent Bercot ififelse, là một phần của execline. Đây không phải là iftrong câu hỏi, mặc dù.
JdeBP

2
"Thực sự không phải là quá xa vời khi nghĩ về nếu, sau đó và các chương trình bên ngoài khác" Vâng, đó là, bởi vì chúng không phải là.
Cuộc đua nhẹ nhàng với Monica

2

Các thenelsekhông phải là chương trình. Các phần khác là. Lưu ý rằng không có ;'trực tiếp sau họ, nhưng sau lệnh họ đi trước.

Đây [ ... ] một lệnh và cần ;nếu theo sau bởi một lệnh khác.

AFAIK, tất cả các cấu trúc điều khiển trong Bash, và có lẽ hầu hết các vỏ * nix, đều giống nhau. Họ là những hướng dẫn cho thông dịch viên. Mặt khác, kiểm tra hoặc điều kiện sử dụng một chương trình / quy trình được "thực thi" và là các lệnh. Vì thenlà một phần của dòng dẫn đến echolệnh, nó phải được phân tách bằng một dòng mới từ lệnh trước đó [ ... ]. Nó không cần phải được tách ra khỏi lệnh mà nó điều khiển , echo yes.

Về mặt pháp lý, mặc dù xấu và khó đọc, bạn cũng có thể làm điều này.

if [ $VARIABLE == abcdef ]
then echo yes
else echo no
fi

Lưu ý rằng không cần ;giữa các điều khiển ở đây, mặc dù chúng không nằm trên đường dây riêng của chúng.

Thật thú vị, toàn bộ cấu trúc điều khiển ( if ... fi) là một lệnh shell và toàn bộ phải kết thúc bằng một dòng mới hoặc a ;. Dòng cuối cùng không thể fi echo donenhưng phải fi; echo done. Giống như một nhiệm vụ VARIABLE='abcdef'là một lệnh.

Mặc dù toàn bộ cấu trúc điều khiển là các lệnh, chúng vẫn không phải là chương trình.


1

if, elif, then, Và fiđược tất cả các từ khóa dành riêng sử dụng để thực hiện một trong những cấu trúc được gọi là một lệnh hợp chất trong vỏ, có nghĩa là không thể có một lệnh (hay đúng hơn, lệnh khác) bởi bất kỳ của những tên trong vỏ. Mục đích ;chung nói chung không phải là tách các lệnh, mà là chấm dứt một danh sách lệnh . Ví dụ: dưới đây là một iftuyên bố hợp lệ :

if echo foo; echo bar; echo baz; then echo done; echo really done; fi

Điều kiện của ifcâu lệnh là danh sách lệnh echo foo; echo bar; echo baz. Trình phân tích cú pháp biết rằng điều kiện đã kết thúc bởi vì then, ngay sau dấu chấm phẩy, không thể là một lệnh vì nó là một từ khóa dành riêng. Vì vậy, nó biết rằng những gì tiếp theo then là sự khởi đầu của cơ thể. Tương tự, filà một từ khóa dành riêng và do đó không thể là một lệnh thứ ba trong phần thân của ifcâu lệnh, nhưng đánh dấu sự kết thúc của lệnh ghép.


cảm ơn, nếu điều này được sử dụng if program1 foo; program2 bar; program3 baz; , trạng thái chương trình nên là gì 0, để shell tiến hành then? Cái cuối cùng?
Maxim Koretskyi

Chỉ cần program3 baz. Trạng thái thoát của danh sách các lệnh là trạng thái thoát của lệnh cuối cùng trong danh sách đó. Hai cái còn lại có thể thất bại mà không ảnh hưởng đến tình trạng.
chepner
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.