TL; DR : Tại sao nhóm niềng răng POSIX cần khoảng trắng sau {
từ dành riêng nhưng subshell không sau từ dành riêng (
?
Ngữ pháp shell POSIX định nghĩa nhóm nẹp và subshell như sau
brace_group : Lbrace compound_list Rbrace
subshell : '(' compound_list ')'
Bây giờ, nếu chúng ta đọc theo nghĩa đen, không gian là đáng kể. Điều này có nghĩa là phải có không gian phân định mở và đóng dấu ngoặc và dấu ngoặc đơn như trong
{ echo hello world; }
( echo hello world )
Điều này cũng sẽ phù hợp với các định nghĩa Lệnh Hợp chất :
Mỗi lệnh ghép này có một từ hoặc toán tử điều khiển dành riêng ở đầu và một từ kết thúc hoặc toán tử dành riêng tương ứng ở cuối.
Tuy nhiên, điều không có ý nghĩa là tại sao (list)
và ( list )
chỉ hoạt động tốt (không gian đó sau đó (
là không bắt buộc), tuy nhiên việc mở rộng niềng răng phải có một không gian hàng đầu, tức là {echo hello;}
sẽ không hoạt động.
Tất nhiên, từ dành riêng được coi là từ vỏ sẽ có nghĩa là cần một khoảng trắng sau đó để phù hợp với khái niệm phân tách trường , tuy nhiên định nghĩa tự nó không đề cập đến khoảng trắng. Hơn nữa, nếu {
và (
cả hai đều được coi là các từ dành riêng theo định nghĩa POSIX của lệnh ghép, tại sao chúng được xử lý khác nhau về ký tự khoảng trắng sau các từ dành riêng này? Bây giờ, hướng dẫn ksh (1) hiện trạng thái:
Các từ, là chuỗi các ký tự, được phân cách bằng các ký tự khoảng trắng không được trích dẫn (dấu cách, tab và dòng mới) hoặc ký tự meta (<,>, |,;, &, (và))
Nói cách khác, nó có ý nghĩa rằng ksh sẽ nhận ra (
là dấu phân cách từ, trong đó từ đầu tiên sẽ là một lệnh hoặc gán biến. POSIX, tuy nhiên dường như không đề cập đến (
như là siêu ký tự. Lời giải thích khả dĩ duy nhất tôi tìm thấy theo ngữ pháp POSIX là nó {
được coi là "mã thông báo", trong đó (
không được liệt kê là một.
/* These are reserved words, not operator tokens, and are
recognized when reserved words are recognized. */
%token Lbrace Rbrace Bang
/* '{' '}' '!' */
Vì vậy, lý do chính xác cho sự khác biệt này là gì?
Ghi chú trả lời được chấp nhận:
Đã chuyển dấu kiểm được chấp nhận vào câu trả lời của Isaac vì nó cung cấp cho q uote mẫu chính tiêu chuẩn trực tiếp giải quyết câu hỏi của tôi:
Chẳng hạn, '(' và ')' là các toán tử điều khiển, do đó không
<space>
cần thiết trong (danh sách). Tuy nhiên, '{' và '}' là các từ dành riêng trong {list;}, do đó, trong trường hợp này là hàng đầu<space>
và<semicolon>
được yêu cầu.Chấp nhận câu trả lời của Kusalananda. Câu trả lời của Kusalananda giải quyết những gì tôi cần, mặc dù chủ yếu theo quan điểm không chính thức và trực quan; nó chỉ ra{
là một từ dành riêng và(
là toán tử. Michael Homer cũng lưu ý tương tự trong các bình luận - rằng trạng thái định nghĩa Lệnh Hợp chất (nhấn mạnh thêm):Mỗi lệnh ghép này có một từ dành riêng hoặc toán tử điều khiển ở đầu
{
được định nghĩa là từ dành riêng, tương tựfor
hoặcwhile
, được liệt kê trong Shell Grammar (xem khối mã cuối cùng trong câu hỏi)Mục 2.9 tiểu bang (nhấn mạnh thêm):
Cụ thể, các biểu diễn bao gồm khoảng cách giữa các mã thông báo ở một số nơi
<blank>
không cần thiết (khi một trong số các mã thông báo là toán tử).Trong khi tiêu chuẩn không xác định rõ ràng
(
là một toán tử,(
được gọi là toán tử; cụ thể, mục 2.9.2 nóiNếu đường ống bắt đầu với từ dành riêng! và lệnh1 là một lệnh con, ứng dụng sẽ đảm bảo rằng (toán tử ở đầu lệnh1 được tách biệt với! bởi một hoặc nhiều ký tự. Hành vi của từ dành riêng! ngay lập tức theo sau (toán tử là không xác định.
Câu hỏi về Stack Overflow của Digital Trauma chỉ ra Phần 2.4 về các từ dành riêng:
Sự công nhận này chỉ xảy ra khi không có ký tự nào được trích dẫn và khi từ được sử dụng là:
-Từ đầu tiên của một lệnh
Như đã đề cập trong câu trả lời của Kusalananda "Các khoảng trắng hiển thị trong ngữ pháp POSIX không phải là khoảng trắng cần có trong dữ liệu đầu vào shell, mà chỉ là một cách hiển thị ngữ pháp. Đó là thực tế rằng dấu ngoặc nhọn là những từ dành riêng ngụ ý rằng chúng phải được bao quanh bởi khoảng trắng "Như Michael Homer đã đề cập trong các bình luận:" Nếu các không gian có ý nghĩa theo cách riêng của chúng, thì chúng cần phải được liệt kê trong sản xuất "
Trường hợp đóng cửa.
{
và (
cả hai đều được coi là từ dành riêng theo định nghĩa POSIX của lệnh ghép" "Mỗi lệnh ghép này có một từ dành riêng hoặc toán tử điều khiển ở đầu".
' '
). Thay vào đó, các không gian được ngụ ý bởi những gì các token là từ.
command : simple_command | compound_command | compound_command redirect_list | function_definition ;
là một sản xuất mà nói, nơi bạn có thể có một lệnh, nó có thể là một trong những lệnh đơn giản, chỉ huy hợp chất, hoặc lệnh phức hợp với chuyển hướng, hoặc định nghĩa hàm.