为何`for i do cmd; done`无需分隔符?该语法为何合法?
for i do echo $i; done work without a semicolon before do? Great question! Let’s break down why this syntax is valid across bash, dash, zsh, ksh, and aligns with POSIX standards.
First, let’s reference the POSIX specification for the for loop structure:
for name [ in [word ... ]] do compound-list done
The key detail here is that when you omit the in clause and its associated word list, the reserved word do can directly follow the loop variable name (i in your example).
Shells treat reserved words like do as syntax markers—they don’t need an explicit separator (like a semicolon) to be recognized as part of the loop structure. Think of it like how you can write if [ -f file ] then ... fi (without a semicolon before then) when there’s a newline; the reserved word itself acts as a boundary that the shell’s parser picks up on.
Your expected syntax for i; do echo $i; done is also valid, but the semicolon there is optional in this case. When do follows immediately after the loop variable (with no in clause), the shell knows exactly where the variable declaration ends and the loop body starts, thanks to do being a reserved word.
Another way to look at it: when you omit the in clause, the for loop defaults to iterating over the positional parameters ("$@"). The syntax for i do ... is just a concise way to write for i in "$@" do ..., and the shell’s parser doesn’t require a semicolon to separate i from do here.
All the shells you mentioned (bash, dash, zsh, ksh) adhere strictly to this POSIX rule, which is why the syntax works consistently across them.
内容的提问来源于stack exchange,提问作者William Pursell

