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

Reply via email to