The following bash script:
#!/bin/bash
TEST_VAR=""
if [[ -z $TEST_VAR ]] then
echo "empty"
else
echo "$TEST_VAR"
fi
despite missing a semicolon before "then", does not throw an error in bash 5.2 and completes successfully, even returning 0
.
Running the above script on a system running bash 5.1 or 5.0 fails as expected.
Why is this? Did bash change their parser in version 5.2? After searching I can't find any reference to this change. Did bash intentionally change behavior here, or is this a bug?
Thanks to oguz ismail, who provided proofs to back up my intuition that I wasn't able to find - both the relevant mailing list discussion and the git commit that implemented this.
In a nutshell, following a mailing list discussion happened before the release of 5.2, it had been found that the behavior of [[]]
requiring a semicolon at the end was inconsistent with that of other compound commands, which didn't require a semicolon at the end, and [[]]
's behavior was changed to conform to those before 5.2 rolled out.
]]
is a reserved word:
$ LANG=C type ]]
]] is a shell keyword
From Reserved Words (Bash Reference Manual) - emphasys mine:
Reserved words are words that have special meaning to the shell. They are used to begin and end the shell’s compound commands.
And [[ expression ]]
is, in fact, a compound command.
Historically, other compound commands such as {}
or ()
never required a semicolon after them:
$ if { true; } then echo foo; fi # no semicolon after the first `}`, no syntax error
foo
$ if ( true ) then echo foo; fi # no semicolon after the first `)`, no syntax error
foo
$ if { true; } then { echo foo; } fi # no semicolon after the second `}`, no syntax error either
foo
So [[]]
's behavior was changed to conform to those before 5.2 rolled out.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With