Basic usage of if statement in bash scripting
if [ CONDITION ]; then
FIRST_COMMANDS
elif [ CONDITION ]; then
SECOND_COMMANDS
else
THRID_COMMANDS
fi
- Always use space between the brackets in the condition.
-
Always terminate the line with
;
before adding a new keywordif [ CONDITION ]; then
-
Use
!
to invert the conditionif [ ! CONDITION ]; then
Combine conditions using
-a
for AND, and-o
for OR
There are three syntaxes for define the condition
1. Single-bracket
Support 3 types of conditions
File-based condition
-
[ -a file ]
or[ -e file ]
: if the file is exists -
[ -d directory ]
: if the directory is exists and it's a directory -
[ -r file ]
: if the file is exists and is readable to the script -
[ -w file ]
: if the file is exists and is writeable to the script -
[ -x file ]
: if the file is exists and is executable to the script [ -s file ]
: if the file is exists and has a size of more than 0 bytes[ file1 -ef file2]
: if the files refer to the same device/inode number[ file1 -nt file2]
: if the file1 was changed more recently than file2, or if file1 exists and file2 doesn't[ file1 -nt file2]
: if the file1 was changed longer ago than file2, or if file1 exists and exists[ -N file ]
: if the file is exists and was modified after the last read[ -g file ]
: if the file is exists and is a set-group-ID[ -u file ]
: if the file is exists and is a set-user-ID[ -G file ]
: if the file is exists and is owned by the effective group ID[ -O file ]
: if the file is exists and is owned by the user executing the script[ -b file ]
: if the file is exists and is a block special[ -c file ]
: if the file is exists and is a character special[ -f file ]
: if the file is exists and is a regular file[ -h file ]
or[ -L file ]
: if the file is exists and is a symbolic link[ -k file ]
: if the file is exists and has its sticky bit set[ -p file ]
: if the file is exists and is a named pipe[ -S file ]
: if the file is exists and is a socket[ -t file ]
: if the file descriptor is exists and refers to an open terminal
String-based condition
-
[ STRING1 == STRING2 ]
: if equal -
[ STRING1 != STRING2 ]
: if not equal -
[ -n STRING ]
: if has length of more than zero -
[ -z STRING ]
: if an empty string -
[ STRING =~ PATTERN ]
: if match the regex pattern
Arithmetic condition
-
[ NUM1 -eq NUM2 ]
: if equal -
[ NUM1 -ne NUM2 ]
: if not equal -
[ NUM1 -gt NUM2 ]
: if greater than -
[ NUM1 -ge NUM2 ]
: if greater than equal -
[ NUM1 -lt NUM2 ]
: if less than -
[ NUM1 -le NUM2 ]
: if less than equal
2. Double-bracket
This is the enhanced version of single-bracket. All features in single-bracket syntax are compatible here. We can start using this syntax.
The differences :
-
Can use regex
[[ STRING =~ PATTERN ]]
: if match the regex pattern Can use
&&
and||
instead of-a
and-o
3. Double-parenthesis
This is another syntax for arithmetic condition
-
(( NUM1 == NUM2 ))
: if equal -
(( NUM1 != NUM2 ))
: if not equal -
(( NUM1 > NUM2 ))
: if grater than -
(( NUM1 >= NUM2 ))
: if grater than equal -
(( NUM1 < NUM2 ))
: if less than -
(( NUM1 <= NUM2 ))
: if less than equal
We also can quickly test a condition like this
# using &&
[ $foo == "bar" ] && echo true
# using ||
[ $foo == "bar" ] || echo true
Top comments (2)
You list
[ STRING =~ PATTERN ]
in your single-bracket conditions, but then go on to say it's different in double-bracket conditions. What did you mean?I think the main benefit of using single-brackets is that those conditions will likely work in other shells, even if they're not as powerful.
Nice catch man, thanks.
Updated. That regex should work with double brackets
[[ STRING =~ PATTERN ]]