David542
David542

Reputation: 110203

Spacing and newlines in bash

What is the reason why the following fails:

if [ 'asdf' == 'eff' ] then
    echo You may go to the party.
else
    echo You may not go to the party.
fi

But the following is OK:

if [ 'asdf' == 'eff' ]
then
    echo You may go to the party.
else
    echo You may not go to the party.
fi

Does then have to be on its own line or what are the spacing/newline requirements for it?

Upvotes: 0

Views: 267

Answers (2)

Gordon Davisson
Gordon Davisson

Reputation: 125798

The thing that comes after if is a command (or pipeline, or series of commands, or...). If you use

if [ 'asdf' == 'eff' ] then

...the shell will parse that as the beginning of an if statement, containing the command [ 'asdf' == 'eff' ] then ... that is, the command [ (yes, that's a command, synonymous with test) with the arguments "asdf", "==", "eff", "]", and ... "then". Since there's no delimiter, the then is treated as just another argument to the [ command, and it'll keep looking for the then on subsequent lines!

Consider this example:

if echo some words here then

Here, since there's no ] to be a visual indicator of the end of the test command, it's obvious there's a problem. But while ] looks like a delimiter, it isn't actually syntactically significant to the shell; it's just another argument to the [ command.

To prevent this, you need a command delimiter of some sort -- a line break or a semicolon (or technically even & though that's a bad idea) before the then, so the then will be parsed as a keyword rather than just an argument to some other command.

BTW, using == in a [ ] test isn't standard. bash's builtin version of the [ command allows it, but some others don't. If you're writing specifically for bash, I'd recommend using [[ ]] instead (which has cleaner syntax). If you're writing for portability, use [ = ] instead.

So, either of these is ok:

if [ 'asdf' = 'eff' ]; then
    ...

or

if [ 'asdf' = 'eff' ]
then
    ...

Upvotes: 2

Ron
Ron

Reputation: 6601

The reason is that after the condition you either need new line or ;

if you do:

if [ 'asdf' == 'eff' ]; then

this will not fail

You can also do all of it in one line:

if [ 'asdf' == 'eff' ]; then echo You may go to the party.; else echo You may not go to the party.;fi

Upvotes: 4

Related Questions