Test values in Bash
test
is a built-in command that is used to compare values or determine whether something is the case.
We can use the command test
but it is more common to test a condition implicity by using square brackets. The square brackets are an alias for test
. We use this alias when we use IF
logic.
When we run a test the result we get back is a return status of a 0
or a 1
. 0
indicates that the test was a success and 1
means failure. (Bear in mind this is in contrast to most all other programming languages.)
If we run a test in the command line we won’t get a 0
or a 1
or back, there will just be silence from the shell. We can explicitly invoke the return value with variable $?
, e.g:
[ -d ~ ] # is the home directory a directory?
echo $?
0 # yes
[ -d /bin/zsh ] # is this binary a directory?
echo $
1 # no
Test structures
Many tests can be run with flags as a shorthand like we saw above:
File operators
-a FILE True if file exists.
-d FILE True if file is a directory.
-e FILE True if file exists.
-h FILE True if file is a symbolic link
-s FILE True if file exists and is not empty.
-N FILE True if the file has been modified since it was last read.
String operators
-z STRING True if string is empty.
-n STRING True if string is not empty.
Differences between comparing numbers and strings
=
is reserved for comparing strings- For numbers we use, e.g,
[ 4 -lt 5 ]
Negation
We can negate a test condition with !
:
[ ! 4 -lt 3 ]; echo $?
0
Running process if test succeeds or fails
We can use the following structure to run a process if a test condition obtains:
[[ -d ~ ]] && echo "/home is a directory"
Extended test: [[...]]
When we use double brackets we are using extended test
.
The extended test supports the standard test
comparisons and adds other features:
- The use of Boolean operators:
[[ -d ~ || -a /bin/mash ]]; echo $?
Using regular expressions
Extended test also allows us to use regular expressions as part of our test conditions. In order to test against a regular expression we use =~
as the comparison operator.
[[ "thomas" =~ t.* ]]; echo $?
Here the test succeeds because “thomas” begins with “t” followed by any other character.
Further examples
Test if a character exists in two strings
string1="hello"
string2="world"
char="l"
if [[ "$string1" == *"$char"* ]] && [[ "$string2" == *"$char"* ]]; then
echo "Character '$char' exists in both strings."
else
echo "Character '$char' does not exist in both strings."
fi
Note: this syntax can also be used to test if a given element exists in an array.