ทำไมคุณไม่สามารถย้อนกลับลำดับของโอเปอเรเตอร์การเปลี่ยนเส้นทางอินพุตในขณะที่ลูปได้


11

ใน Bash คุณสามารถย้ายโอเปอเรเตอร์การเปลี่ยนเส้นทางอินพุตไปยังด้านหน้าของคำสั่ง:

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

ทำไมคุณไม่ทำเช่นเดียวกันกับลูปในขณะที่?

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'

ฉันคิดว่ามันค่อนข้างสับสนเพราะคุณสามารถไปป์ในขณะที่ ฉันกำลังทำอะไรผิดหรือเป็นเพียงการตัดสินใจออกแบบหรือไม่

คำตอบ:


16

มันเป็นเพียงผลสืบเนื่องจากการกำหนดไวยกรณ์ จากข้อมูลจำเพาะไวยากรณ์ของ POSIX Shell :

command          : simple_command
                 | compound_command
                 | compound_command redirect_list
                 | function_definition
                 ;

และ:

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
                 ;

อย่างที่คุณเห็นเมื่อใช้คำสั่งผสมการเปลี่ยนเส้นทางได้รับอนุญาตหลังจากเท่านั้น แต่ด้วยคำสั่งแบบง่ายจะได้รับอนุญาตก่อนเช่นกัน ดังนั้นเมื่อเปลือกเห็น<redirection> foo, fooจะถือว่าเป็นคำสั่งที่เรียบง่ายไม่ได้เป็นคำสั่งผสมและwhileได้รับการปฏิบัติไม่เป็นคำหลัก:

$ < foo while
bash: while: command not found

ดังนั้นสิ่งที่doไม่คาดคิดเนื่องจากอนุญาตหลังจากคำหลักบางคำเท่านั้น

ดังนั้นสิ่งนี้ไม่เพียง แต่เป็นการwhileวนซ้ำ แต่วิธีส่วนใหญ่ในการตั้งค่าคำสั่งผสมโดยใช้คำสงวน:

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

คำอธิบายที่ดีขอบคุณ
philraj
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.