Mengapa Anda tidak dapat membalik urutan operator pengalihan input untuk sementara loop?


11

Di Bash Anda dapat memindahkan operator pengalihan input ke bagian depan perintah:

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

Mengapa Anda tidak dapat melakukan hal yang sama untuk loop sementara?

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'

Saya merasa sedikit membingungkan karena Anda dapat menyalurkan ke loop sementara. Apakah saya melakukan sesuatu yang salah atau itu hanya keputusan desain?

Jawaban:


16

Itu hanya konsekuensi dari bagaimana tata bahasa didefinisikan. Dari spesifikasi Tata Bahasa POSIX Shell :

command          : simple_command
                 | compound_command
                 | compound_command redirect_list
                 | function_definition
                 ;

Dan:

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
                 ;

Seperti yang Anda lihat, dengan perintah majemuk, pengalihan hanya diperbolehkan setelahnya , tetapi dengan perintah sederhana, itu juga diizinkan sebelumnya. Jadi, ketika shell melihat <redirection> foo, foodiperlakukan sebagai perintah sederhana, bukan perintah majemuk, dan whiletidak lagi diperlakukan sebagai kata kunci:

$ < foo while
bash: while: command not found

Karenanya, doini tidak terduga, karena hanya diperbolehkan setelah kata kunci tertentu.

Jadi ini berlaku tidak hanya untuk whileloop, tetapi sebagian besar cara mengatur perintah majemuk menggunakan kata-kata yang dipesan:

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

Penjelasan yang bagus, terima kasih.
philraj
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.