elif: Not a Tolkien Character

elif is a portmanteau consisting of the words "else" and "if".  In bash (and Python), it's a way to test multiple statements before closing a loop, as opposed to the single statement test provided by else.  If a typical if/then construct uses an if/then/else format, elif allows for if/then/elif/then/else.

Here is a simple example that will try to start mysql if mariadb is active on the system,  psql if postgresql is active on the system. Below the example is a breakdown of what each line does:

[user@host ~]$ systemctl is-active mariadb > /dev/null 2>&1 
MARIADB_ACTIVE=$? 
[user@host ~]$ systemctl is-active postgresql > /dev/null 2>&1 
POSTGRESQL_ACTIVE=$? 
[user@host ~]$ if [ "$MARIADB_ACTIVE" -eq 0 ]; then 
> mysql 
> elif [ "$POSTGRESQL_ACTIVE" -eq 0 ]; then 
> psql 
> else 
> echo "Nuts, all outta databases here!" 
> fi
  1. This line asks systemctl to check if the mariadb service is-active, and to send any output (error or otherwise) to /dev/null, or nowhere.
    Fun Fact: 2>&1 Refers to something very basic about how Unix systems operate: standard input (stdin), standard output (stdout) and standard error (stderr).
    stdin (0) is a keyboard - what you use to input information
    stdout (1) is the terminal - where output is displayed
    stderr (2) are errors.
    So 2>&1 is saying to send any errors (2) from this command to the same location as standard output (1), which in this case is /dev/null, the black hole of all Linux filesystems.
  2. Set a variable called MARIADB_ACTIVE, the value of which is the result of $?, which returns exit codes from the immediately previous command.  If mariadb was active, the exit code would be 0. If it's not running, or not installed, it would be another number, between 1 and 255.  In this instance, mariadb is not installed, so the exit code is 3.
    Unfamiliar with exit codes? In bash, you can check the exit code of the previous command by typing echo $?, which will output EITHER a 0 or any other number.  If the previous command was successful, you always get a 0.  Any other number is a fail.
  3. Ask systemctl to check if the postgresql service is-active and send any output (and errors) to /dev/null.
  4. Set a variable called POSTGRESQL_ACTIVE with the value of the exit code $? for the command from the previous line.  In this instance, postgresql is also not installed, so the exit code is 3.
  5. If/then loop using a test expression.  This is saying that if the value of the variable MARIADB_ACTIVE is equal (-eq) to 0, then
  6. Run mysql if the previous line can be processed.  In this instance, the value of MARIADB_ACTIVE is 3, so the test failed, and we go to the next line:
  7. elif (else if) the previous command failed, try another test expression - in this case, if the value of POSTGRESQL_ACTIVE is equal (-eq) to 0, then
  8. Run psql if the test expression succeeded - it didn't, because the value of POSTGRESQL_ACTIVE is 3, so we go to the next line:
  9. else - if elif failed and can't run psql on the previous line, go to the next line
  10. Neither mariadb nor postgresql is installed, so we're just going to output text that says "Nuts, all outta databases around here!".
  11. fi - The inverse of if and closes out the if/then loop.

Just for super geeky funsies, let's write a bash script to cover Bilbo's thought processes about taking the ring back at Rivendell, using elif:

systemctl is-active mordor-desire > /dev/null 2>&1
MORDOR_DESIRE=$?
systemctl is-active wanna-turn-into-a-gollum /dev/null 2>&1
GOLLUM_DESIRE=$?
if [ "$MORDOR_DESIRE" -eq 0 ]; then
> echo "I'm going on an adventure!"
> elif [ "$GOLLUM_DESIRE" -eq 0 ]; then
> echo "REEEEEEEEEEEEEE"
> else
> echo "I'm sorry that you must carry this burden"
> fi
elif [ "$GOLLUM_DESIRE" -eq 0 ]; then echo "REEEEEEEEEEEEEE"
patrick

patrick