Bash / Shell Conditional Flags¶
Bash conditionals are essential.
Conditionals in bash are done with flags and equality operators.
Table of Contents¶
- Bash / Shell Conditional Flags
- Files and Directories
- Arithmetic Operators
- Conditionals for Strings and Variables
- File Descriptors
- Name Reference
- Checking if Certain Shell Options are Enabled
- Bash Conditional Flags Table
Files and Directories¶
These are the "primaries," the primary unary or binary conditional operators.
By default, primaries that operate on files follow symbolic links and operate
on the target of the link, rather than the link itself.
When used with [[
, the <
and >
operators sort lexicographically using the current locale.
The test
command sorts using ASCII ordering.
Flag | True if |
---|---|
-a file |
File exists. |
-b file |
File is block special. |
-c file |
File is character special. |
-d file |
File is a directory. |
-e file |
File exists. |
-f file |
File exists and is a regular file. |
-s file |
File exists and has a size greater than zero (not empty). |
-r file |
File is readable by you. |
-w file |
File is writable by you. |
-x file |
File is executable by you. |
-O file |
File is owned by you. |
-G file |
File is owned by your group. |
-h file |
File is a symbolic link. |
-L file |
File is a symbolic link. |
-g file |
File is set-group-id . |
-u file |
File is set-user-id . |
-k file |
File has its sticky bit set. |
-p file |
File is a named pipe. |
-S file |
File is a socket. |
-N file |
File has been modified since it was last read. |
file1 -ef file2 |
file1 is a hard link to file2 . |
file1 -nt file2 |
file1 is newer than file2 (uses the modification date). |
file1 -ot file2 |
file1 is older than file2 . |
-t fd |
"file descriptor" is opened on a terminal. |
Arithmetic Operators:¶
These are the arithmetic operators that are allowed inside bracket notation (either
double [[ ... ]]
or single [ ... ]
brackets, or with test
):
-eq
: Is equal to-ne
: Not equal to-lt
: Less Than-le
: Less than or equal to-gt
: Greater than-ge
: Greater than or equal to
if [[ $somevar -gt 0 ]]; then
printf "Greater than zero.\n"
fi
These arithmetic operators in Bash can be used inside double parentheses (( ... ))
,
in let
statements, and in declare
statements when using -i
(declare -i ...
).
==
: Is equal to!=
: Not equal to<
: Less Than<=
: Less than or equal to>
: Greater than>=
: Greater than or equal to
if (( somevar > 0 )); then
printf "Greater than zero.\n"
fi
Note that you don't need to use
$
when calling variables inside the arithmetic evaluation.
Conditionals for Strings and Variables¶
-v varname
: True if the shell variable varname is set (has been assigned a value).-
-R varname
: True if the shell variable varname is set and is a name reference. -
-z string
: True if the length of string is zero. -
-n string
: True if the length of string is non-zero. -
string1 == string2
- string1 = string2
- True if the strings are equal.
=
should be used with thetest
command for POSIX-compliance.- When used with the
[[
command, this performs pattern matching as described in (man://bash 280
).
-
string1 =~ regex
: True ifstring1
matches the regular expressionregex
.- This is not POSIX-compliant (bash-only).
-
string1 != string2
: True if the strings are not equal. string1 < string2
: True if string1 sorts before string2 lexicographically (alphabetically).string1 > string2
: True if string1 sorts after string2 lexicographically (alphabetically).
File Descriptors¶
In Linux/Unix, a file descriptor is a non-negative number that uniquely identifies an open file for the process.
Standard file descriptors:
0
: standard input (stdin)1
: standard output (stdout)2
: standard error (stderr)
File Descriptor Usage Example:¶
if [[ -t 0 ]]; then
printf "Standard Input is attached to a terminal.\n"
else
printf "Standard Input is not attached to a terminal.\n"
fi
if [[ -t 1 ]]; then
printf "Standard Output is attached to a terminal.\n"
else
printf "Standard Output is not attached to a terminal.\n"
fi
Name Reference¶
Like a pointer in C.
A name reference is a variable that refers to another variable.
This is different from a normal variable assignment.
The name reference creates a kind of alias to the other variable.
A name reference is created using the declare -n
command.
Name Reference Usage Example:¶
declare -n ref=original
original="data"
if [[ -R ref ]]; then
echo "ref is a name reference."
else
echo "ref is not a name reference."
fi
Checking if Certain Shell Options are Enabled¶
-o optname
- True if the shell option
optname
is enabled. - The list of options appears in the output of
set -o
.
- True if the shell option
Bash Conditional Flags Table¶
See man://bash 2069
.
Flag | True if |
---|---|
-a file |
File exists. |
-b file |
File exists and is a block special file. |
-c file |
File exists and is a character special file. |
-d file |
File exists and is a directory. |
-e file |
File exists. |
-f file |
File exists and file is a regular file. |
-g file |
File exists and is set-group-id. |
-h file |
File exists and is a symbolic link. |
-k file |
File exists and its sticky bit is set. |
-p file |
File exists and is a named pipe (FIFO). |
-s file |
File exists and has a size greater than zero. |
-t fd |
File descriptor fd is open and refers to a terminal. |
-u file |
File exists and its set-user-id bit is set. |
-r file |
File exists and is readable. |
-w file |
File exists and is writable. |
-x file |
File exists and is executable. |
-G file |
File exists and is owned by the effective group id. |
-L file |
File exists and is a symbolic link. |
-N file |
File exists and has been modified since it was last read. |
-O file |
File exists and is owned by the effective user id. |
-S file |
File exists and is a socket. |
file1 -ef file2 |
file1 and file2 refer to the same device and inode numbers. |
file1 -nt file2 |
file1 is newer than file2 , or if file1 exists and file2 does not (uses modification date). |
file1 -ot file2 |
file1 is older than file2 , or if file2 exists and file1 does not. |
-v varname |
True if the shell variable varname is set (has been assigned a value). |
-R varname |
True if the shell variable varname is set and is a name reference. |
-z string |
True if the length of string is zero. |
-n string |
True if the length of string is non-zero. |
string1 == string2 |
True if the strings are equal. |
string1 =~ regex |
True if string1 matches the regular expression regex (bash-only). |
string1 != string2 |
True if the strings are not equal. |
string1 < string2 |
True if string1 sorts before string2 lexicographically (alphabetically). |
string1 > string2 |
True if string1 sorts after string2 lexicographically (alphabetically). |
case
¶
Case statements in Bash are a way to check the value of a single variable against multiple values.
The general syntax is:
case "$var" in
one)
printf "Var is 'one'!\n"
;;
two)
printf "Var is 'two'!\n"
;;
*)
printf "Var is not 'one' OR 'two'!\n"
;;
esac
This will check the value of var
against the patterns specified in each of the
cases, each followed with a closing parenthese )
.
Each case is terminated with double semicolons (;;
).
The last case *
is the default case. This will only be triggered if no other
cases matched.
This is functionally equivalent to:
if [[ $var == one ]]; then
printf "Var is 'one'!\n"
elif [[ $var == two ]]; then
printf "Var is 'two'!\n"
else
printf "Var is not 'one' OR 'two'!\n"
fi
Once a case pattern is matched, the block of code inside will run and the case
statement will stop testing that value against the cases.
Other Case Terminators¶
Instead of using double semicolons to terminate cases (;;
), you can use others to
change how the case
statement behaves.
-
;&
: After executing the current pattern's block, continue testing the next pattern with the same input.- It will use the same input and continue testing it against each case.
-
;&
: After executing the current pattern's block, unconditionally execute the next pattern's block (without re-testing).- This could potentially be useful as a handler... but at that point, just write a handler function (in my opinion).