463

I can't seem to work out what the issue with the following if statement is in regards to the elif and then. Keep in mind the printf is still under development I just haven't been able to test it yet in the statement so is more than likely wrong.

The error I'm getting is:

./timezone_string.sh: line 14: syntax error near unexpected token `then'
./timezone_string.sh: line 14: `then'

And the statement is like so.

if [ "$seconds" -eq 0 ];then
   $timezone_string="Z"
elif[ "$seconds" -gt 0 ]
then
   $timezone_string=`printf "%02d:%02d" $seconds/3600 ($seconds/60)%60`
else
   echo "Unknown parameter"
fi
5
  • 10
    I wonder why we need the then statement in if and elif but not in else, and also in general. Commented Jul 16, 2017 at 4:50
  • 3
    @w17t, because we need to separate condition from sequence. Commented Jan 2, 2019 at 20:40
  • 6
    @codeforester I don't see much logic on marking a 500K views question as a duplicate to one that has only 5K Commented May 15, 2019 at 9:41
  • Using some code auto-formatting tools might help you by automatically adding/removing spaces around the brackets. You can search for plugins for your editor. Commented Jun 7, 2019 at 17:09
  • for me , i never expected a semicolon at the end of 'if' statement followed by 'then'.Your question itself was the solution for me. Thanks a lot !! Commented Jun 15, 2021 at 10:05

5 Answers 5

589

There is a space missing between elif and [:

elif[ "$seconds" -gt 0 ]

should be

elif [ "$seconds" -gt 0 ]

All together, the syntax to follow is:

if [ conditions ]; then
   # Things
elif [ other_conditions ]; then
   # Other things
else
   # In case none of the above occurs
fi

As I see this question is getting a lot of views, it is important to indicate that the syntax to follow is:

if [ conditions ]
# ^ ^          ^

meaning that spaces are needed around the brackets. Otherwise, it won't work. This is because [ itself is a command.

The reason why you are not seeing something like elif[: command not found (or similar) is that after seeing if and then, the shell is looking for either elif, else, or fi. However it finds another then (after the mis-formatted elif[). Only after having parsed the statement it would be executed (and an error message like elif[: command not found would be output).

Sign up to request clarification or add additional context in comments.

8 Comments

The reason the brackets need spaces is because they are just shortcuts for actual programs (at least the first bracket, the second one is just syntactic sugar as I understand it). To make sense of it, see the actual manpage for left bracket: $ man [
Is this post not supposed to be closed as typo?
@zx8754 could have been, but not it became a canonical way to fix this error, which looks quite useful (360K views and counting).
Some of my colleagues don't understand the concept of a "space" or "coding style" so this might not be a typo.
[ is a kind of alias for the test command. This is why the blank character is required. if test "$seconds" -eq 0; then ... fi is equivalent to if [ "$seconds" -eq 0 ];then ... fi ]. @LeiYang man testis what you actually looking for
|
349

You have some syntax issues with your script. Here is a fixed version:

#!/bin/bash

if [ "$seconds" -eq 0 ]; then
   timezone_string="Z"
elif [ "$seconds" -gt 0 ]; then
   timezone_string=$(printf "%02d:%02d" $((seconds/3600)) $(((seconds / 60) % 60)))
else
   echo "Unknown parameter"
fi

5 Comments

Oddly enough, this was the only complete and simple bash "if-then-else" construct I easily found on stackexchange...thanks.
indentation is optional. the interpreter can (and should) be #!/bin/sh.
@Chinggis6 Total nonsense, the interpreter could be #!/bin/sh but doesn't have to.
@Camusensei it's not a total nonsense as sh can be used instead for higher compatibility (not all *nix distros has bash as the default shell (some have ksh or ash but most of them do depend on the standard sh to function). Moreover if bash's specific or advanced features is not being used in the script then 'sh' should be used as the interpreter (one more reason for it) as it can handle the script by itself.
@Chinggis6 True, bad choice of words on my side.
30

[ is a command (or a builtin in some shells). It must be separated by whitespace from the preceding statement:

elif [

2 Comments

It is superseeded by a builtin in bash, but your message is still correct. use type -a [ to see that.
It's also a binary which always seemed odd to me.
9

I would recommend you having a look at the basics of conditioning in bash.

The symbol "[" is a command and must have a whitespace prior to it. If you don't give whitespace after your elif, the system interprets elif[ as a a particular command which is definitely not what you'd want at this time.

Usage:

elif(A COMPULSORY WHITESPACE WITHOUT PARENTHESIS)[(A WHITE SPACE WITHOUT PARENTHESIS)conditions(A WHITESPACE WITHOUT PARENTHESIS)]

In short, edit your code segment to:

elif [ "$seconds" -gt 0 ]

You'd be fine with no compilation errors. Your final code segment should look like this:

#!/bin/sh    
if [ "$seconds" -eq 0 ];then
       $timezone_string="Z"
    elif [ "$seconds" -gt 0 ]
    then
       $timezone_string=`printf "%02d:%02d" $seconds/3600 ($seconds/60)%60`
    else
       echo "Unknown parameter"
    fi

Comments

6

Missing space between elif and [ rest your program is correct. you need to correct it an check it out. here is fixed program:

#!/bin/bash

if [ "$seconds" -eq 0 ]; then
   timezone_string="Z"
elif [ "$seconds" -gt 0 ]; then
   timezone_string=$(printf "%02d:%02d" $((seconds/3600)) $(((seconds / 60) % 60)))
else
   echo "Unknown parameter"
fi

useful link related to this bash if else statement

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.