Neden döngüler için giriş yeniden yönlendirme operatörünün sırasını tersine çeviremiyorsunuz?


11

Bash'te giriş yeniden yönlendirme işleçlerini komutun önüne taşıyabilirsiniz:

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

Aynı şeyi neden döngüler için yapamıyorsunuz?

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'

Bir süre döngüsüne girebileceğiniz için biraz kafa karıştırıcı buluyorum . Yanlış bir şey mi yapıyorum yoksa bu sadece bir tasarım kararı mıydı?

Yanıtlar:


16

Bu sadece dilbilgisinin nasıl tanımlandığının bir sonucudur. Gönderen POSIX Kabuk Dilbilgisi şartname :

command          : simple_command
                 | compound_command
                 | compound_command redirect_list
                 | function_definition
                 ;

Ve:

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
                 ;

Gördüğünüz gibi, bileşik komutlarla yeniden yönlendirmeye yalnızca sonradan izin verilir , ancak basit komutlarla daha önce de izin verilir. Bu nedenle, kabuk gördüğünde <redirection> foo, foobileşik bir komut değil, basit bir komut olarak ele alınır ve whileartık bir anahtar kelime olarak ele alınmaz :

$ < foo while
bash: while: command not found

Bu nedenle, doyalnızca belirli anahtar kelimelerden sonra izin verildiğinden, beklenmedik bir durumdur.

Bu sadece whiledöngüler için değil , ayrılmış sözcükler kullanarak bileşik komutlar oluşturmanın çoğu yolu için geçerlidir :

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

Güzel açıklama, teşekkür ederim.
philraj
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.