Tại sao bạn không thể đảo ngược thứ tự của toán tử chuyển hướng đầu vào trong khi các vòng lặp?


11

Trong Bash, bạn có thể di chuyển các toán tử chuyển hướng đầu vào sang phía trước của lệnh:

cat <<< "hello"
# equivalent to
<<< "hello" cat

Tại sao bạn không thể làm tương tự trong khi vòng lặp?

while read -r line; do echo "$line"; done <<< "hello"
# hello

<<< "hello" while read -r line; do echo "$line"; done
# -bash: syntax error near unexpected token `do'

Tôi thấy nó hơi khó hiểu vì bạn có thể chuyển thành một vòng lặp while. Tôi đang làm gì đó sai hay đó chỉ là một quyết định thiết kế?

Câu trả lời:


16

Đó chỉ là hệ quả của cách xác định ngữ pháp. Từ đặc tả ngữ pháp POSIX Shell :

command          : simple_command
                 | compound_command
                 | compound_command redirect_list
                 | function_definition
                 ;

Và:

simple_command   : cmd_prefix cmd_word cmd_suffix
                 | cmd_prefix cmd_word
                 | cmd_prefix
                 | cmd_name cmd_suffix
                 | cmd_name
                 ;
[...]
cmd_prefix       :            io_redirect
                 | cmd_prefix io_redirect
                 |            ASSIGNMENT_WORD
                 | cmd_prefix ASSIGNMENT_WORD
                 ;
cmd_suffix       :            io_redirect
                 | cmd_suffix io_redirect
                 |            WORD
                 | cmd_suffix WORD
                 ;

Như bạn có thể thấy, với các lệnh ghép, chuyển hướng chỉ được phép sau , nhưng với các lệnh đơn giản, nó cũng được cho phép trước. Vì vậy, khi shell nhìn thấy <redirection> foo, foođược coi là một lệnh đơn giản, không phải là lệnh ghép và whilekhông còn được coi là một từ khóa:

$ < foo while
bash: while: command not found

Do đó, điều donày là bất ngờ, vì nó chỉ được phép sau một số từ khóa nhất định.

Vì vậy, điều này không chỉ áp dụng cho whilecác vòng lặp, mà hầu hết các cách thiết lập lệnh ghép sử dụng các từ dành riêng:

$ < foo {
bash: {: command not found
$ < foo if
bash: if: command not found
$ < foo for
bash: for: command not found

Lời giải thích tốt đẹp, cảm ơn bạn.
philraj
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.