I am quite sure in almost all the scripts we always end up with one or more conditional checks which requires if
and else
statement. So bash is not different and even in shell scripting we get the requirement to use similar decision making logic.
You can use bash if else
in any section of your shell script such as for loops, while loops, functions etc. This can be further enhanced to use if..elif..else
and nested if so we will cover all such possible scenarios in this tutorial guide.
I will try to be as descriptive as possible from my side so that even an absolute beginner can understand and start using this in their script. But you must be familiar with below two topics
- How to perform comparison between two or multiple strings
- How to perform comparison between two or multiple integers or numbers
As most of the time you will end us using these conditional operators with if
statements
if..fi statement
The very first and basic if
statement would be with single condition.
Syntax
The syntax to use this statement would be:
if [CONDITION]
then
COMMAND
fi
The one liner syntax would be:
if [CONDITION]; then COMMAND1; COMMAND2; fi
- You can replace
CONDITION
with any kind of check which requires a decision - If the
CONDITION
returnsTRUE
i.e.SUCCESS
thenCOMMAND
will be executed - if the
CONDITION
returnsFALSE
i.e.FAILED
then this will do nothing as we don't have anyelse
statement CONDITION
is sort of mandatory here, now thisCONDITION
can be a lot of things which basically requires aDECISION
Flowchart
Shell script Example
Let us look at some shell script examples to understand this properly:
- In this script I have defined two variables and assigned a number to both the variables
- We want to check if
VAR1
is greater than or equal toVAR2
so we are using comparison operator for numbers
# cat /tmp/shell_script.sh #!/bin/bash VAR1=10 VAR2=5 if [[ $VAR1 -ge $VAR2 ]] then echo "$VAR2 is less than or equal to $VAR1" fi
Make sure you give executable permission to your script
# chomd u+x /tmp/shell_script.sh
Execute the script and verify the output:
# /tmp/shell_script.sh
5 is less than or equal to 10
The one liner version of this script would be:
# VAR1=10; VAR2=5; if [[ $VAR1 -ge $VAR2 ]]; then echo "$VAR2 is less than or equal to $VAR1"; fi
5 is less than or equal to 10
if..else..fi statement
I would recommend to always use "else
" statement wherever possible because ELSE
condition denotes FAILED
scenario.
Syntax
I will explain this with some examples but first let us check the syntax for using if..else..fi
in bash
if [CONDITION]
then
SUCCESS_COMMAND
else
FAILED_COMMAND
fi
The one liner syntax for this would be:
if [CONDITION]; then SUCCESS_COMMAND ; else FAILED_COMMAND ; fi
- The syntax is similar to
if..fi
statement, with a single difference that now we also have anelse
statement - So if
CONDITION
isTRUE
thenSUCCESS_COMMAND
would be executed - if
CONDITION
isFALSE
thenFAILED_COMMAND
would be executed - When we say
TRUE
andFALSE
, we mean the exit code of the condition should be0
to beTRUE
and non-zero to beFALSE
Flowchart
Shell script Example-1
Let us enhance our last example with comparison operator but this time we will modify the variable values:
#!/bin/bash VAR1=10 VAR2=50 if [[ $VAR1 -ge $VAR2 ]] then echo "exit_status is: $?" echo "$VAR2 is less than or equal to $VAR1" else echo "exit_status is: $?" echo "$VAR2 is greater than or equal to $VAR1" fi
The output from this script:
exit_status is: 1
50 is greater than or equal to 10
- The
CONDITION
was checking if$VAR1
is greater than equal to$VAR2
- Since
VAR1
is NOT greater thanVAR2
in this script, the condition becomes FALSE i.e. non-zero exit code - So for FALSE condition, the
else
statement is executed
Shell script Example-2
Let us take one practical example, in this script we are trying to locate a file by the name data_file
inside /opt
#!/bin/bash FILE=`find /opt -name data_file -type f` # Check if FILE variable is empty or not if [[ ! -z $FILE ]] then echo "exit_status is: $?" echo "\$FILE variable is not empty, which means file found" echo "File path: $FILE" else echo "exit_status is: $?" echo "\$FILE variable is empty, so file not found" fi
In this script we will
- Find for a
file
nameddata_file
under/opt
- Store the path of the found file in
FILE
variable - IF the file is found the the length of
FILE
variable will be non-zero so we will verify the same using-z
. If you are not familiar with this I would recommend reading about comparison operators - Check the status of
find
command usingif..else..fi
statement
The output from the script for success scenario i.e. when the file is found under /opt
exit_status is: 0
$FILE variable is not empty, which means file found
File path: /opt/data_file
Shell script Example-3
Now in this example we had store the path into variable, this is required only if you want to process the files which are found. If you just want to check if the files are there or not, you can use the find
command in the if
condition:
if find /opt -name data_file -type f >& /dev/null then echo "exit_status is: $?" echo "\$FILE variable is not empty, which means file found" echo "File path: $FILE" else echo "exit_status is: $?" echo "\$FILE variable is empty, so file not found" fi
So I am running the complete find
command in the if
statement instead of storing it in variable. Make sure you send the output of such commands to NULL (>& /dev/null
) or else you will get output on the screen which will not look good
if..elif..else..fi statement
You can add multiple conditions between if..else
statement by using elif
.
Syntax
The syntax to use this would be:
if CONDITION_1
then
COMMAND
elif CONDITION_2
then
COMMAND
..
else
COMMAND
fi
You can add multiple elif
in the block between if..else
statement depending upon your requirement. The else
statement is optional and you can choose to only use if..elif..fi
if CONDITION_1
then
COMMAND
elif CONDITION_2
then
COMMAND
..
fi
Flowchart
Shell script Example-1
- The check would happen in sequential order from top to bottom so you should place your conditions accordingly in the same order.
- Let us evaluate
if..elif..else..if
statement with some shell script examples: - In this script I have two variables namely
VAR1
andVAR2
for which both I have assigned the same value - Now in the
if
condition I will check if$VAR1
is greater than or equal to$VAR2
- In
elif
block I will check if$VAR1
is equal to$VAR2
- The
else
block will be executedif
bothif
andelif
condition returnFALSE
#!/bin/bash VAR1=10 VAR2=10 if [[ $VAR1 -ge $VAR2 ]] then echo "exit_status is: $?" echo "$VAR2 is less than or equal to $VAR1" elif [[ $VAR1 -eq $VAR2 ]] then echo "exit_status is: $?" echo "$VAR2 is equal to $VAR1" else echo "exit_status is: $?" echo "$VAR2 is greater than or equal to $VAR1" fi
The output from this script
exit_status is: 0
10 is less than or equal to 10
So the first condition was TRUE
because VAR1
is greater than or equal to VAR2
Did you noticed the mistake I did here?
- I have added duplicate conditions in
if
andelif
block. - This is something which I was trying to highlight earlier, that bash will execute this in sequential order so you should know how to put the conditions
- The
elif
block will never be called if bothVAR1
andVAR2
are equal as that will match in theif
condition - The proper way to do it would be either use
-gt
in the if condition to only check for greater than or you create a separateif..fi
block only to check ifVAR1
andVAR2
are equal
Shell script Example-2
This shell script example also uses multiple if
and elif
blocks
#!/bin/bash VAR1=10 if [[ $VAR1 -eq 5 ]] then echo "exit_status is: $?" echo "$VAR1 is equal to 5, matched in if block" elif [[ $VAR1 -eq 10 ]] then echo "exit_status is: $?" echo "$VAR1 is equal to 10, matched in elif block" else echo "$VAR1 is neither equal to 5 nor 10, no match found" fi
The condition is trying to match VAR1
is certain value and based on the match, respective block would be executed. The output from this script:
exit_status is: 0
10 is equal to 10, matched in elif block
Please NOTE
for if
and elif
block the CONDITION
should be TRUE
for the respective block to be executed. If the CONDITION
is FALSE
then else
block will be executed.
Nested if statement
If can also put if
condition inside another if..elif..else..fi
block.
Syntax
The syntax to use nested if
condition would be same as earlier, we just need to add the if
block inside existing section of COMMAND
if CONDITION_1
then
if [ CHILD_CONDITION_1 ]
then
NESTED_COMMAND
elif [ CHILD_CONDITION_1 ]
then
NESTED_COMMAND
..
fi
elif CONDITION_2
then
if [ CHILD_CONDITION_1 ]
then
NESTED_COMMAND
elif [ CHILD_CONDITION_1 ]
then
NESTED_COMMAND
..
fi
..
else
COMMAND
fi
Here using elif
and else
is optional, I have only placed it there for better understanding. You can choose to only use nested if
without elif
and else
block
Shell script Example
Let us understand this better with some shell script example:
- In this script, I will prompt
user
to give some numbers as input separated by white space character - We will store this input into
NUM
variable - Then we will check if
NUM
is empty of not using the firstif
condition - If
NUM
is empty i.e. user has not provided any input thenelse
condition will be executed - If user gives some input then we have again created
nested if block
under the mainif block
- This
nested if
condition will count the numbers available inNUM
variable - I have used
wc -w
to count the number of words inNUM
variable - Then based on this value I will check if number of words in
NUM
variable is equal to 1 or 2 or 3 or more than 3 in respectivenested if..elif..elif..else
block
#!/bin/bash read -r -p "Enter a list of numbers separated by whitespace char: " NUM if [[ ! -z $NUM ]] then echo "Good, the user has provided some input" echo "But how may words has user given as input?, Let me check" WORD_COUNT=`echo $NUM | wc -w` if [ $WORD_COUNT -eq 1 ];then echo "User has given one number as input" elif [ $WORD_COUNT -eq 2 ];then echo "User has given two numbers as input" elif [ $WORD_COUNT -eq 3 ];then echo "User has given three numbers as input" else echo "User has given more than 3 numbers as input" fi else echo "\$NUM is empty, did you provide any input?" fi
The output from this script when I give more than 3 input words
Enter a list of numbers separated by whitespace char: 1 2 3 4 Good, the user has provided some input But how may words has user given as input?, Let me check User has given more than 3 numbers as input
The output from this script if I don't give any input
Enter a list of numbers separated by whitespace char: $NUM is empty, did you provide any input?
if multiple condition
Now above we only had a single condition per if..elif
condition. But we can also add multiple conditional operator in single if condition
Syntax 1: Using square braces
There are different syntax you can use for putting multiple condition in single if
condition
if [[ CONDITION_1 || CONDITION_2 ]] || [[ CONDITION_3 && CONDITION_4 ]]
then
SUCCESS_COMMAND
else
FAILED_COMMAND
fi
You can use ||
to put OR
condition and &&
to use AND
condition. Replace these condition operator in the above syntax as per your requirement
We will use this syntax in our sample script to compare two numbers
#!/bin/bash read -r -p "Enter first number: " NUM1 read -r -p "Enter second number: " NUM2 if [[ $NUM1 -eq 1 || $NUM -eq 2 ]] || [[ $NUM1 -eq 3 && $NUM2 -eq 4 ]] then echo "SUCCESS" else echo "FAILED" fi
Syntax 2: Using parenthesis
You can also use double parenthesis instead of square braces with similar conditional operator as used with square braces:
if (( CONDITION_1 || CONDITION_2 )) || (( CONDITION_3 && CONDITION_4 ))
then
SUCCESS_COMMAND
else
FAILED_COMMAND
fi
We will use this syntax in our sample script to compare two numbers
#!/bin/bash read -r -p "Enter first number: " NUM1 read -r -p "Enter second number: " NUM2 if (( $NUM1 -eq 1 || $NUM -eq 2 )) || (( $NUM1 -eq 3 && $NUM2 -eq 4 )) then echo "SUCCESS" else echo "FAILED" fi
Syntax 3: Combine parenthesis with square brace
The third syntax would be combination of parenthesis and square braces:
if [ \( CONDITION_1 -a CONDITION_2 \) -o \( CONDITION_3 -a CONDITION_4 \) ]
then
SUCCESS_COMMAND
else
FAILED_COMMAND
fi
Here -a
represents AND
condition and -o
represents OR
condition. You can choose to add more blocks or just use single block in these syntax based on your requirement.
In this example we will compare two number's value using different conditional operator with single parenthesis and curly braces
#!/bin/bash read -r -p "Enter first number: " NUM1 read -r -p "Enter second number: " NUM2 if [ \( "$NUM1" -eq 1 -a "$NUM2" = 2 \) -o \( "$NUM1" -eq 3 -a "$NUM2" = 4 \) ] then echo "SUCCESS" else echo "FAILED" fi
This is another practical example where we will ask for user confirmation as INPUT
with Yes/No
: It is possible end user gives Yes
or YES
or yes
/No
or NO
or no
so we need to handle all these answers:
#!/bin/bash read -r -p "Do you want to confirm: " INPUT if [ \( "$INPUT" == "YES" -o "$INPUT" == "Yes" -o "$INPUT" == "yes" \) ] then echo "SUCCESS with Yes" elif [[ $INPUT == "NO" || $INPUT == "No" || $INPUT == "no" ]] then echo "SUCCESS with No" else echo "Unable to identify the answer" fi
In the if
condition we are using -o
to check the OR
condition across all the answers for YES
and with elif
we are using ||
to check the OR
condition across all the answers for NO
The output from this script if user gives "Yes
" as INPUT
:
Do you want to confirm: Yes
SUCCESS with Yes
The output from this script if user gives "No
" as INPUT
:
Do you want to confirm: No
SUCCESS with No
The out from this script where there is some un-supported INPUT
Do you want to confirm: None
Unable to identify the answer
Conclusion
In this tutorial we learned about different possible syntax which we can use with if..else
statement in bash
. It is important that you are familiar with different comparison operator used for strings, integers, under parenthesis etc because without proper conditional operator you may get errors like
[: YES: integer expression expected
syntax error near unexpected token
[: too many arguments
syntax error in conditional expression
and similar other errors.
The if
condition in bash is very useful but you must check the order in which which you perform the check, as I have also shown in this tutorial, bash will perform sequential check from top to bottom.
If you do not arrange your if..elif..elif..else..fi
condition, then most likely the results will not be correct. Lastly I hope the steps from the article to use bash if else
statement on Linux was helpful. So, let me know your suggestions and feedback using the comment section.
Thank you very much!
Never seen such a well documented HowTO
Regards, wim dukker