On Sat, Aug 14, 2021, at 6:59 PM, George Nachman wrote: > Description: > Defining an alias named `done` breaks parsing a for loop that does not have > an `in word` clause. > > > Repeat-By: > > Run the following script. It fails with this error: > > myscript.bash: line 7: syntax error near unexpected token `done' > myscript.bash: line 7: ` done' > > > #!/bin/bash > > alias done="" > > f() { > for var; do > done > }
The 'alias' command is irrelevant because aliases are not expanded in noninteractive shells by default. The absence of 'in X' is also irrelevant. The problem is that there cannot be *nothing* between 'do' and 'done'. (I'll let someone more patient relate this to the formal grammar, if they're so inclined.) % bash --version | head -n 1 GNU bash, version 5.1.8(1)-release (x86_64-apple-darwin18.7.0) % cat /tmp/myscript1.bash f() { for var in a b c; do done } % bash /tmp/myscript1.bash /tmp/myscript1.bash: line 3: syntax error near unexpected token `done' /tmp/myscript1.bash: line 3: ` done' You *can* force alias expansion by setting expand_aliases, in which case you get a different error. % cat /tmp/myscript2.bash alias done='' f() { for var in a b c; do done } % bash -O expand_aliases /tmp/myscript2.bash /tmp/myscript2.bash: line 6: syntax error near unexpected token `}' /tmp/myscript2.bash: line 6: `}' This is the same error you'd get if you simply omitted 'done' entirely, which should make sense. > Fix: > `done` should not be considered a simple command in the context where it > would terminate a for loop. POSIX mode does disable alias expansion in that situation (see <https://www.gnu.org/software/bash/manual/html_node/Bash-POSIX-Mode.html>, item 7). Perhaps the default behavior is for backward compatibility? % bash --posix /tmp/myscript2.bash /tmp/myscript2.bash: line 5: syntax error near unexpected token `done' /tmp/myscript2.bash: line 5: ` done' -- vq