It is a normal or I would say daily use case for a Linux developer to work on a script which requires comparison of strings. But I have seen many people tend to get confused between strings and integers. So before we go ahead and learn about string comparison in bash, let us understand the basic different between bash and integer value.
Difference between Integers and Strings
Now in bash we have strings and integers. So any text provided under single quotes (’’) or double quotes ("") is considered as string. So even if you provide a numerical value under single or double quotes which by default should be an integer but due to the quotes it will be considered as string.
Let us take some examples to understand the difference between string and integer in bash:
For examples:
VAL="text" => Here text is a string
VAL="10" => Here 10 is a string even though this is an integer as it is provided with double quotes
VAL='11' => Again for the same reason 11 will be considered as string as it is under single quotes
VAL=11 => Here 11 is integer so this needs separate handling for bash string comparison
Comparison operators for strings
First let us understand the different comparison operator available for sting comparison in bash and shell script.
| Name | Operator syntax | Syntax with single bracket | Syntax with double brackets | Comment |
|---|---|---|---|---|
| is equal to | =(or)== |
[ "string1" = "string2" ] |
[[ "$string1" == "string2" ]] |
Returns TRUE if both the operands are equal |
| is not equal to | != |
[ "string1" != "string2" ] |
[[ "string1" != "string2" ]] |
Returns TRUE if both the operands are NOT equal |
| is less than | < |
[ "string1" \< "string2" ] |
[[ "string1" < "string2" ]] |
Use escape character for the operator in single bracket Returns TRUE if the right operand is considered lower than the left operand The comparison is done using ASCII alphabetical order |
| is greater than | > |
[ "string1" \> "string2" ] |
[[ "string1" < "string2" ]] |
Use escape character for the operator in single bracket Returns TRUE if the right operand is considered higher than the left operand The comparison is done using ASCII alphabetical order |
| zero string length | -z |
[ -z "string2" ] |
[[ -z "string2" ]] |
Returns TRUE if the provided String has zero length i.e. null value |
| non zero length | -n |
[ -n "string2" ] |
[[ -n "string2" ]] |
It is IMPORTANT that the string is under inverted commas Returns TRUE if string is non-zero i.e. not null |
Check if Strings are Equal
Bash compares strings by length and each character match. For example in this shell script I have defined both variables with same string
VAR1="golinuxcloud"
VAR2="golinuxcloud"
if [[ "$VAR1" == "$VAR2" ]];then
echo "exit status: $?"
echo "$VAR1 is equal to $VAR2"
else
echo "exit status: $?"
echo "$VAR1 is NOT equal to $VAR2"
fi
The output from this script shows that the first condition returns TRUE with exit status as zero so both strings are considered EQUAL
exit status: 0
golinuxcloud is equal to golinuxcloud
If we run this in DEBUG mode (the best thing I like about shell scripts)
+ VAR1=golinuxcloud
+ VAR2=golinuxcloud
+ [[ golinuxcloud == \g\o\l\i\n\u\x\c\l\o\u\d ]]
+ echo 'exit status: 0'
exit status: 0
+ echo 'golinuxcloud is equal to golinuxcloud'
golinuxcloud is equal to golinuxcloud
As you see, bash is comparing both the string’s length and each character before returning TRUE status
Check if Strings are NOT Equal
We will make some change in one of our variables and then perform the string comparison
VAR1="golinuxcloud"
VAR2="website"
if [[ "$VAR1" != "$VAR2" ]];then
echo "exit status: $?"
echo "$VAR1 is NOT equal to $VAR2"
fi
The output of this script shows the first condition returns TRUE with exit status as zero so both strings are not equal
exit status: 0
golinuxcloud is NOT equal to website
Compare strings using ASCII order
I have personally not used this in my career till now, I would be
interested to know if any my readers have any use case to use such
comparison for strings
I have taken two variables with two different strings
VAR1="A"
VAR2="B"
if [[ "$VAR1" > "$VAR2" ]];then
echo "exit status: $?"
echo "$VAR1 is greater than $VAR2"
elif [[ "$VAR1" == "$VAR2" ]];then
echo "exit status: $?"
echo "$VAR1 is equal to $VAR2"
else
echo "exit status: $?"
echo "$VAR1 is lesser than $VAR2"
fi
The output of this script would be
exit status: 1
A is lesser than B
Because as per
ASCII code Letter A has ASCII code of
065 while Letter B has 066 so Letter A is considered lesser
than B
Check if string is empty
This is one of the most used operator in real time production environment where we are collecting output from some command into a variable and want to make sure that the variable is not empty i.e. it was able to collect the command output
In this script I am trying to get PID of a dummy process so it is expected that the variable will be empty
VAR=`pidof dummy`
if [ -z "$VAR" ]; then
echo "exit status: $?"
echo "\$VAR is null."
else
echo "exit status: $?"
echo "\$VAR is NOT null."
echo "value: $VAR"
fi
Output from this script confirms that our string is empty and returns TRUE
exit status: 0
$VAR is null.
In this script I will look for PID of java process
VAR=`pidof java`
if [ -z "$VAR" ]; then
echo "exit status: $?"
echo "\$VAR is null."
else
echo "exit status: $?"
echo "\$VAR is NOT null."
echo "value: $VAR"
fi
Output from this script tells us that the VAR string is not empty and returns FALSE
exit status: 1
$VAR is NOT null.
value: 10592
Check if string is non-zero or not-null
We can use the same script to verify if the variable is non-zero.
The difference is with -z we get zero exit when string has no value
while the just opposite with -n which will return zero exit status if
the string is non-zero
VAR=`pidof java`
if [ -n "$VAR" ]; then
echo "exit status: $?"
echo "\$VAR is NOT null."
else
echo "exit status: $?"
echo "\$VAR is null."
echo "value: $VAR"
fi
The output from the script
exit status: 0
$VAR is NOT null.
Shell Script: string comparison operator examples
We will check some examples to understand and learn bash string comparison.
Here I have created a single script which will use all the bash string comparison operators we learned about in a while loop so that I don’t have to write separate function to demonstrate an example. This loop will continue to run unless I manually send an interrupt signal to the script:
# cat /tmp/bash_compare_strings.sh
#!/bin/bash
# Bash Compare Strings
# Run the script untill manually interrupted
while true; do
# Collect VAR1 and VAR2 value from end user
read -r -p "Enter VAR1 value: " VAR1
read -r -p "Enter VAR1 value: " VAR2
# Check if $VAR1 value is less that $VAR2
if [[ "$VAR1" < "$VAR2" ]];then
echo "$VAR1 is less than $VAR2"
# Check if $VAR1 value is greater than $VAR2
elif [[ "$VAR1" > "$VAR2" ]];then
echo "$VAR1 is greater than $VAR2"
# Check if $VAR1 is equal to $VAR2
elif [[ "$VAR1" == "$VAR2" ]];then
echo "$VAR1 is equal to $VAR2"
# Chcek if $VAR1 is not equal to $VAR2
elif [[ "$VAR1" != "$VAR2" ]];then
echo "$VAR1 is NOT equal to $VAR2"
else
# If none of the above condition matches
echo "Unable to get the status"
fi
done
Now we will give different values to VAR1 and VAR2 in this script and check the exit status. If you observe I have placed both variables under double quotation mark so even if you give numbers as an input to this script, they will be considered as strings.
Provide executable permission to the script
# chmod u+x /tmp/bash_compare_strings.sh
Let us execute our script to learn more about bash compare strings operator:
# /tmp/bash_compare_strings.sh
Enter VAR1 value: deepak
Enter VAR1 value: deepak
deepak is equal to deepak <- We know both the strings are same
Enter VAR1 value: deepak
Enter VAR1 value: amit
deepak is greater than amit <- deepak has more number of char compared to amit
Enter VAR1 value: amit
Enter VAR1 value: deepak
amit is less than deepak <- amit has less number of char compared to deepak
Enter VAR1 value: 100
Enter VAR1 value: 100
100 is equal to 100 <- both the strings are same
Enter VAR1 value: deep100
Enter VAR1 value: deep101
deep100 is less than deep101 <- we have combined text with number. deep is same in both variables but 100 is less than 101
Enter VAR1 value: deep100
Enter VAR1 value: amit101
deep100 is greater than amit101 <- This depends on the combination of ASCII code value
Perform regex and pattern (=~) match for strings
We will check some more examples to compare bash regex match and bash pattern match. Here I have written a one liner shell script to check for bash regex match and bash pattern match.
[root@controller ~]# [[ "my name is deepak prasad" =~ "prasad"$ ]] && echo "bash regex match" || echo "bash regex nomatch"
bash regex match
We can also break this into multi line script which will be easier to understand for new comers
if [[ "my name is deepak prasad" =~ "prasad"$ ]]; then
echo "bash regex match"
else
echo "bash regex nomatch"
fi
Here we use =~ instead of == to
match a pattern and
dollar $sign to match the
last word of the string. Now since “prasad” is the last word in
my name is deepak prasad hence the bash pattern match is successful.
Similarly I check the for starting word using ^ in my string, now
since my is the starting word in my name is deepak prasad the bash
pattern match is successful.
[root@controller ~]# [[ "my name is deepak prasad" =~ ^"my" ]] && echo "bash regex match" || echo "bash regex nomatch"
bash regex match
We can also look out for certain word within a string without any regex
as shown below. Since deepak word is present in
my name is deepak prasad, the bash pattern match is successful
[root@controller ~]# [[ "my name is deepak prasad" =~ "deepak" ]] && echo "bash regex match" || echo "bash regex nomatch"
bash regex match
By default if we use “is equal to” for the below check then it says
“nomatch” as with == the shell will try to match character to
character for both the variables due to which the check fails
[root@controller ~]# [[ "my name is deepak prasad" == "deepak" ]] && echo "bash regex match" || echo "bash regex nomatch"
bash regex nomatch
So we use wildcard (*) regex to match the string to ignore starting
and ending text, the bash regex match is successful.
[root@controller ~]# [[ "my name is deepak prasad" == *"deepak"* ]] && echo "bash regex match" || echo "bash regex nomatch"
bash regex match
Conclusion
Bash is still one of the most used programming language across industry although it is being taken over by Python, Go and other languages which serve more advantage but I still feel it your script contains more of system commands then bash is still the preferred language for Administrators and Developers. In this tutorial guide we learned about different string comparison operators, performing regex and pattern match for strings using different examples.
Lastly I hope the steps from the article to perform string comparison in shell scripts on Linux was helpful. So, let me know your suggestions and feedback using the comment section.
References
I have used below external references for this tutorial guide
Comparison
Operators
ASCII
Binary Character Table


