0

I likely have syntax errors in the following (POSIX) shell snippet:

#!/bin/sh
if tput setaf >/dev/null 2>&1; then tput_init_linux else tput_init_none;
elif tput AF  >/dev/null 2>&1; then tput_init_bsd   else tput_init_none;
else tput_init_none; fi

ShellCheck 0.10.0 does say nothing about it, I found it basically by accident.

I tested as follows:

  1.  

    if tput setaf >/dev/null 2>&1; then tput_init_linux else tput_init_none; fi
    

    this went ok: tput_init_linux: command not found

  2. Reverting the logic with !:

    if ! tput setaf >/dev/null 2>&1; then tput_init_linux else tput_init_none; fi
    

    says nothing, but if I add one semicolon:

  3.  

    if ! tput setaf >/dev/null 2>&1; then tput_init_linux; else tput_init_none; fi
    

    it appears to work as expected: tput_init_none: command not found


But I seem to be unable to chain these multiple if-statements afterward.


So as you can see, I reached a state, where one statement works, but chaining it seems problematic. Can anyone help?

0

1 Answer 1

3

You have two syntax errors. First, either a semicolon or a newline is required. This is wrong1:

if condition; then command1 else command2; fi

But these are correct:

if condition; then command1; else command2; fi

or

if condition; then 
 command1 
else 
command2
fi

Next, the if/elif/else/fi is opened by the if and closed by the else followed by the fi. The elif only goes in the middle and you can have many of those, but only one else. So your attempt is confusing:

if tput setaf >/dev/null 2>&1; then tput_init_linux else tput_init_none;
elif tput AF  >/dev/null 2>&1; then tput_init_bsd   else tput_init_none;
else tput_init_none; fi

Since each if/else pair is binary, I am not sure how you would chain them. Now, I think what you want to do is to only run tput_init_none if neither tput setaf nor tput AF work. If so, you would do:

if tput setaf >/dev/null 2>&1; then 
  tput_init_linux 
elif tput AF  >/dev/null 2>&1; then 
  tput_init_bsd   
else 
  tput_init_none;
fi

Or, same thing:

if tput setaf >/dev/null 2>&1; then tput_init_linux; elif tput AF >/dev/null 2>&1; then tput_init_bsd; else tput_init_none; fi

Basically, you can chain as many if/elif as you like, but there can only be one else. The else is the final, fallback condition that is executed if both the if and all the elif fail.


1 More accurately, this is only a "syntax error" in the sense that this syntax doesn't do what you want it to do. It is actually perfectly valid syntax, but it means "run the command command1 with the arguments else and command2. Since that is actually valid syntax, shellcheck won't pick it up, but it won't do what you expect:

$ if true; then echo TRUE else echo FALSE; fi
TRUE else echo FALSE

So you can think of it like if true; then echo "TRUE" "else" "echo" "FALSE"; fi.

0

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .