Bash Conditional Expressions¶
Conditional Expressions are signals - also called primaries - that bash uses as a means of performing tests, using the info you provide.
Lets say you are wanting to copy over a file from one location to another, but don’t need to do this if the file already exists in the final location. This is one way to test for that!
if [[ ! -e /etc/foo ]]; then
echo "Looks like /etc/foo doesn't exist"
fi
Breakdown¶
[[ ]]
So, the double brackets here are necessary for#!/bin/bash
, of which, to be honest, using the double brackets as the standard setup seems to be what makes the most sense.!
The exclamation point is how you negate expressions through a lot of bash in general. So, here, its testing if/etc/foo
exists.-e
True if File Exists. Its a very broad testing flag.- After the brackets are closed, you use
;
to tell bash that your expression line is finished. - Then, you do whatever you need to do.
fi
then, thefi
is what tells bash thatif
is finished.
Conditional Expression Primaries¶
The following test flags go with:
if [[ -e /bin/bash ]]; then ...
<some code>
elif [[ ! -e /bin/dash ]]; then
<some code>
fi
Use [[ ]]
with double ==
and use [ ]
with =
The first line, -e /bin/bash
is the positive side of the -e FILE
test.
There are a LOT of ways to test things, using either if-then-else
, case
or while
loops.
Flag | Explainer |
---|---|
-a FILE | True if file exists |
-b FILE | True if file exists and is a block special file |
-c FILE | True if file exists and is a character special file |
-d FILE | True if file exists and is a directory |
-e FILE | True if file exists |
-f FILE | True if file exists and is a regular file |
-g FILE | True if file exists and its set-group-id bit is set |
-G FILE | True if file exists and is owned by the effective group id |
-h FILE | True if file exists and is a symbolic link |
-k FILE | True if file exists and its sticky bit is set |
-L FILE | True if file exists and is a symbolic link |
-n STRING | True if the length of string is NON-zero |
-N FILE | True if file exists and has been modified since it was last read |
-o OPTNAME | True if the shell option optname is enabled [1] |
-O FILE | True if file exists and is owned by the effective user id |
-p FILE | True if file exists and is a named pipe (FIFO) |
-r FILE | True if file exists and is readable |
-R $VARNAME |
True if the shell variable $VARNAME is set and is a name reference |
-s FILE | True if file exists and has a size greater than zero |
-S FILE | True if file exists and is a socket |
-t FD | True if file descriptor fd is open and refers to a terminal |
-u FILE | True if file exists and its set-user-id bit is set |
-v $VARNAME |
True if the shell variable $VARNAME is set (has been assigned a value) [2] |
-w FILE | True if file exists and is writable |
-x FILE | True if file exists and is executable |
-z FILE or STRING | True if STRING or FILE is null |
Compare Flags | Explainer |
---|---|
file1 -nt file2 | True if file1 exists and is newer than file2 |
file1 -ot file2 | True if file1 exists and is older than file2 |
file1 -ef file2 | True if file1 and file2 exist and refer to the same file |
Compare Strings | Explainer |
---|---|
s1 == s2 | True if strings s1 and s2 are equal |
s1 = s2 | True if strings s1 and s2 are equal |
s1 != s2 | True if strings s1 and s2 are not equal |
s1 < s2 | True if string s1 comes before s2 based on the binary value of their characters |
s1 > s2 | True if string s1 comes after s2 based on the binary value of their characters |
Note
Bash-based conditionals - #!/bin/bash
- usually prefer you to use double-brackets, [[ ]]
. When you use [[ ]]
, you have to use double-equals - ==
. You can still use the single-brackets with single-equals =
.
But when using sh
- #!/bin/sh
- it prefers single-brackets - [ ]
. When you use the single-brackets, you use single-equals - =
.
Compare Strings | Explainer |
---|---|
n1 -eq n2 | True if the integers n1 and n2 are algebraically equal |
n1 -ne n2 | True if the integers n1 and n2 are not algebraically equal |
n1 -gt n2 | True if the integer n1 is algebraically greater than the integer |
n1 -ge n2 | True if the integer n1 is algebraically greater than or equal to the integer n2 |
n1 -lt n2 | True if the integer n1 is algebraically less than the integer n2 |
n1 -le n2 | True if the integer n1 is algebraically less than or equal to the integer n2 |
Note
See man test
for more explanations.
[1] | Shell Option optname : The list of options appears in the description of the -o option to the set builtin. (see The Set Builtin) |
[2] | $VARNAME is replaceable with ANY VARIABLE name needed |