Table of contents
- Introduction
- Conditionals for the Strings in bash scripting
- Conditionals for Integers
- Bash Conditionals for Files
- Bash Conditionals to check if a file is a character special file or block special file
- Checking whether a file is a directory , regular file or symbolic link using Bash conditionals
- Checking whether a file has read , write or execute permissions using conditionals in bash scripting
- Conditionals for other different file scenarios
- Checking whether the file is existing using conditionals in Bash scripting
- Checking whether a file is a non-empty file using conditionals in bash scripting
- Checking whether a file is a socket file using Bash conditionals
- Using Bash conditionals to validate whether a file is a named pipe file
- Other Bash conditionals available for the files
Introduction
Wondering how to use the conditionals in Bash scripting !
In this article we will be discussing various conditional statements and thier use cases in the bash scripting while using if – else statements
Conditionals for the strings ( single Square bracket types and Double Square bracket types )
Single square bracket Syntax in bash conditionals for Strings
Here in this script , we are comparing two strings whether they are equal and executing the lines if the condition is satisfied , else we are executing different set of lines
[root@discoveringsystems conditionals]# cat bash_script
#!/bin/bash
string_1="this"
string_2="that"
if [ "$string_1" == "$string_2" ]; then
echo "$string_1 is equal to $string_2"
else
echo "$string_1 is not equal to $string_2"
fi
[root@discoveringsystems conditionals]# ./bash_script
this is not equal to that
[root@discoveringsystems conditionals]# cat bash_script
#!/bin/bash
string_1="this"
string_2="this"
if [ "$string_1" == "$string_2" ]; then
echo "$string_1 is equal to $string_2"
else
echo "$string_1 is not equal to $string_2"
fi
[root@discoveringsystems conditionals]# ./bash_script
this is equal to this
We can modify the script to use not equal to instead of equal to
[root@discoveringsystems conditionals]# cat bash_script
#!/bin/bash
string_1="this"
string_2="that"
if [ "$string_1" != "$string_2" ]; then
echo "$string_1 is not equal to $string_2"
else
echo "$string_1 May be equal $string_2"
fi
[root@discoveringsystems conditionals]# ./bash_script
this is not equal to that
[root@discoveringsystems conditionals]# cat bash_script
#!/bin/bash
string_1="this"
string_2="this"
if [ "$string_1" != "$string_2" ]; then
echo "$string_1 is not equal to $string_2"
else
echo "$string_1 may be equal to $string_2"
fi
[root@discoveringsystems conditionals]# ./bash_script
this may be equal to this
Checking whether the string is a empty string using conditionals
Here we are checking the string whether it is a empty string using the -z , if it is a empty string with -z then it returns true
[root@discoveringsystems conditionals]# cat bash_script
#!/bin/bash
read -p "please enter your name : " username
if [ -z "$username" ]; then
echo "value entered is a empty string , please enter a valid username"
else
echo "Welcome $username !"
fi
[root@discoveringsystems conditionals]# ./bash_script
please enter your name : ds-admin
Welcome ds-admin !
[root@discoveringsystems conditionals]# ./bash_script
please enter your name :
value entered is a empty string , please enter a valid username
We can also change the script to use another variation. -n refers to the check for the non-empty string . if its a non empty string with -n then it returns true
[root@discoveringsystems conditionals]# cat bash_script
#!/bin/bash
read -p "please enter your name : " username
if [ -n "$username" ]; then
echo "Welcome $username !"
else
echo "value entered is a empty string , please enter a valid username"
fi
[root@discoveringsystems conditionals]# ./bash_script
please enter your name :
value entered is a empty string , please enter a valid username
[root@discoveringsystems conditionals]# ./bash_script
please enter your name : ds-admin
Welcome ds-admin !
Double Square bracket syntax in bash conditionals for Strings
We can use the double bracket syntax for the string if conditionals when dealing with the globbing (”*”) , regex , etc. Also we can use the string variables for conditionals without the quotes , so mostly an enhanced version of the single bracket syntax
[root@discoveringsystems conditionals]# cat bash_script
#!/bin/bash
read -p "please enter your name : " username
if [[ $username == *admin ]]; then
echo "Welcome $username ! your role is admin"
else
echo "Welcome $username ! your role is operator"
fi
[root@discoveringsystems conditionals]# ./bash_script
please enter your name : ds-admin
Welcome ds-admin ! your role is admin
[root@discoveringsystems conditionals]# ./bash_script
please enter your name : ds-operator
Welcome ds-operator ! your role is operator
[root@discoveringsystems conditionals]# ./bash_script
please enter your name : ds-sys
Welcome ds-sys ! your role is operator
And also it gives the privilege to combine conditional expressions together, In the below example we were able to combine two conditionals with “and” operator , so both the conditionals needs to be true inorder for the combined expression conditional to be true
[root@discoveringsystems conditionals]# cat bash_script
#!/bin/bash
read -p "please enter your name : " username
read -p "please enter your group : " group
if [[ $username == *admin && $group == admin ]]; then
echo "Welcome $username ! your role is admin"
else
echo "Welcome $username ! your role is operator"
fi
[root@discoveringsystems conditionals]# ./bash_script
please enter your name : ds-admin
please enter your group : admin
Welcome ds-admin ! your role is admin
[root@discoveringsystems conditionals]# ./bash_script
please enter your name : ds-admin
please enter your group : other
Welcome ds-admin ! your role is operator
[root@discoveringsystems conditionals]# ./bash_script
please enter your name : ds-operator
please enter your group : admin
Welcome ds-operator ! your role is operator
Conditionals for Integers ( square bracket type and the arithmetic type (( )) )
Square bracket Syntax for Integers in bash conditionals
We can write conditionals for the integers using this Single Square bracket syntax , where we can use the terms like eq ( equal to ) , ne (not equal to) , gt (greater than ) , ge ( greater than or equal to ), lt ( less than ) and le ( lesser than or equal to ).
In the following script , i put together all the terms for comparison which explains how to use them in scripts
[root@discoveringsystems conditionals]# cat bash_script_numbers
#!/bin/bash
one=1
two=2
three=3
four=4
five=5
six=6
if [ $one -eq $one ]; then
echo "$one is equal to $one "
fi
if [ $one -ne $two ]; then
echo "$one is not equal to $two"
fi
if [ $four -gt $two ]; then
echo "$four is greater than $two"
fi
if [ $five -ge $four ]; then
echo " $five is greater than or equal to $four"
fi
if [ $three -lt $five ]; then
echo "$three is less than $five"
fi
if [ $three -le $four ]; then
echo "$three is lesser than or equal to $four"
fi
[root@discoveringsystems conditionals]# ./bash_script_numbers
1 is equal to 1
1 is not equal to 2
4 is greater than 2
5 is greater than or equal to 4
3 is less than 5
3 is lesser than or equal to 4
Double parenthesis syntax for the Arithmetic conditionals on Integers
While using this Syntax , normal operators like “>”( greater than), “>=”(greater than or equal to),”==” , etc are supported. We can also create combined expressions. In the following example we can see how to use them in scripts. Also note the “&&” (and) is used in the script , likewise we can also use “||”(or) operator.
[root@discoveringsystems conditionals]# cat bash_script_numbers
#!/bin/bash
one=1
two=2
three=3
four=4
five=5
six=6
if (( $one == $one )); then
echo "$one is equal to $one "
fi
if (( $one != $two )); then
echo "$one is not equal to $two"
fi
if (( $four > $two )); then
echo "$four is greater than $two"
fi
if (( $five >= $four )); then
echo " $five is greater than or equal to $four"
fi
if (( $three < $five )); then
echo "$three is less than $five"
fi
if (( $three <= $four )); then
echo "$three is lesser than or equal to $four"
fi
if (( $three <= $four && $five >= $four )); then
echo "$three is lesser than or equal to $four and $five is greater than or equal to $four"
fi
[root@discoveringsystems conditionals]# ./bash_script_numbers
1 is equal to 1
1 is not equal to 2
4 is greater than 2
5 is greater than or equal to 4
3 is less than 5
3 is lesser than or equal to 4
3 is lesser than or equal to 4 and 5 is greater than or equal to 4
Bash Conditionals for Files
Bash Conditionals to check if a file is a character special file or block special file
Special files are usually known as Device files. Character special files and the block special files fall under this category.
Block special files can do read / write in blocks. The devices you find under the /dev directory like Usb , Hard disk, etc are block device files. The data access is asynchronous so multiple users can write at the same time.
Here is how to check whether a file is a block special file, we can use the test command with -b option to validate it and the exit status should be 0 for the success and it represents a block device file
[root@discoveringsystems conditionals]# test -b /dev/sda ; echo $?
0
Character special files read / write data in characters. The device files like null , stdin, stderr, stdout etc are considered the character device files. The data access is synchronous so only one user can write at a time.
Here is how to check whether a file is a Character special file , using test command with option -c we can check the file the the exit status for the command needs to be 0 ( success)
[root@discoveringsystems conditionals]# test -c /dev/null ; echo $?
0
[root@discoveringsystems conditionals]# test -c /dev/stderr ; echo $?
0
[root@discoveringsystems conditionals]# test -c /dev/stdout ; echo $?
0
[root@discoveringsystems conditionals]# test -c /dev/stdin ; echo $?
0
Now lets see how we can use file conditionals to identify the block special files and the character special files
[ -c $path_1 ] - Validates whether it is a character special file in if conditionals
[ -b $path_2 ] - Validates whether it is a block special file in if conditionals
[root@discoveringsystems conditionals]# cat bash_script_files
#!/bin/bash
path_1="/dev/null"
path_2="/dev/sda"
if [ -c $path_1 ]; then
echo "$path_1 is a character special file"
else
echo "$path_1 is not a character special file"
fi
if [ -b $path_2 ]; then
echo "$path_2 is a block special file"
else
echo "$path_2 is not a block special file"
fi
[root@discoveringsystems conditionals]# ./bash_script_files
/dev/null is a character special file
/dev/sda is a block special file
Checking whether a file is a directory , regular file or symbolic link using Bash conditionals
In the present working directory , I have 3 files , based on the ” ls -ltrh ” output , I was able to differentiate them as a regular file , directory and symbolic link file.
[root@discoveringsystems conditionals]# ls -ltrh | grep -i test
drwxr-xr-x. 2 root root 6 Feb 24 11:08 test_directory
-rw-r--r--. 1 root root 0 Feb 24 11:08 test_file
lrwxrwxrwx. 1 root root 9 Feb 24 11:10 test_symbolic_link -> test_file
Now we will be seeing an example on how to differentiate them using a bash script
[ -f $path_1 ] - Validates whether it is a regular file
[ -d $path_2 ] - Validates whether it is a directory file
[ -h $path_3 ] - Validates whether it is a symbolic link
[ -L $path_3 ] - Validates whether it is a symbolic link , same as “-h”
[root@discoveringsystems conditionals]# cat bash_script_files
#!/bin/bash
path_1="test_file"
path_2="test_directory"
path_3="test_symbolic_link"
if [ -f $path_1 ]; then
echo "$path_1 is a regular file"
fi
if [ -d $path_2 ]; then
echo "$path_2 is a directory file"
fi
if [ -h $path_3 ]; then
echo "$path_3 is a symbolic_link"
fi
if [ -L $path_3 ]; then
echo "$path_3 is a symbolic_link"
fi
[root@discoveringsystems conditionals]# ./bash_script_files
test_file is a regular file
test_directory is a directory file
test_symbolic_link is a symbolic_link
test_symbolic_link is a symbolic_link
Checking whether a file has read , write or execute permissions using conditionals in bash scripting
We can use the following syntax to achieve the same
[ -r $path_1 ] - validates whether it is a readable file
[ -w $path_1 ] - validates whether it is a writable file
[ -x $path_1 ] - validates whether it is a executable file
From the file permissions we know that the test_file provides read , write , execute permissions to the root user
[root@discoveringsystems conditionals]# ls -ltrh test_file
-rwxr--r--. 1 root root 0 Feb 24 11:08 test_file
We are using a script to validate whether we have those access on the same file
[root@discoveringsystems conditionals]# cat bash_script_files
#!/bin/bash
path_1="test_file"
if [ -r $path_1 ]; then
echo "$path_1 is a readable file"
fi
if [ -w $path_1 ]; then
echo "$path_1 is a writable file"
fi
if [ -x $path_1 ]; then
echo "$path_1 is a executable file"
fi
[root@discoveringsystems conditionals]# ./bash_script_files
test_file is a readable file
test_file is a writable file
test_file is a executable file
Conditionals for other different file scenarios
Checking whether the file is existing using conditionals in Bash scripting:
To check whether the file is existing , we have two formats supported , both does the similar job
[ -a path_1 ] - validates whether it is a existing file
[ -e path_1 ] - validates whether it is a existing file , same as -a
Below is the code example using this conditional , we are testing the presence of the test_file in the current working directory
[root@discoveringsystems conditionals]# ls -ltrh | grep -i test
-rwxr--r--. 1 root root 0 Feb 24 11:08 test_file
lrwxrwxrwx. 1 root root 9 Feb 24 11:10 test_symbolic_link -> test_file
drwxr-xr-x. 2 root root 6 Feb 27 11:17 test_directory
[root@discoveringsystems conditionals]# cat bash_script_files
#!/bin/bash
path_1="test_file"
if [ -a $path_1 ]; then
echo "$path_1 is existing (format -a)"
else
echo "$path_1 is non existing file (format -a)"
fi
if [ -e $path_1 ]; then
echo "$path_1 is existing (format -e) "
else
echo "$path_1 is non-existing file (format -e)"
fi
[root@discoveringsystems conditionals]# ./bash_script_files
test_file is existing (format -a)
test_file is existing (format -e)
Then i removed the test file and the results of the conditionals now changes
[root@discoveringsystems conditionals]# ls -ltrh | grep -i test
lrwxrwxrwx. 1 root root 9 Feb 24 11:10 test_symbolic_link -> test_file
drwxr-xr-x. 2 root root 23 Feb 27 11:21 test_directory
[root@discoveringsystems conditionals]# ./bash_script_files
test_file is non existing file (format -a)
test_file is non-existing file (format -e)
Checking whether a file is a non-empty file using conditionals in bash scripting
We can use the following syntax to validate whether a file is a non-empty file
[ -s path_1 ] - validates whether it is a non empty file of size more than 0 bytes
I have created a empty file for testing
[root@discoveringsystems conditionals]# ls -l | grep -i test_file
-rwxr--r--. 1 root root 0 Feb 24 11:08 test_file
This code example uses the conditionals to check the same
[root@discoveringsystems conditionals]# cat bash_script_files
#!/bin/bash
path_1="test_file"
if [ -s $path_1 ]; then
echo "$path_1 is a non-empty file "
else
echo "$path_1 is an empty file "
fi
[root@discoveringsystems conditionals]# ./bash_script_files
test_file is an empty file
Now to make it an non empty file i added some contents to it , and then the result changes as per the conditionals
[root@discoveringsystems conditionals]# echo "adding some content to the test_file " > test_file
[root@discoveringsystems conditionals]# ls -l | grep -i test_file
-rwxr--r--. 1 root root 38 Feb 27 12:16 test_file
[root@discoveringsystems conditionals]# ./bash_script_files
test_file is a non-empty file
Checking whether a file is a socket file using Bash conditionals
We can use the following command syntax to validate whether it is a socket file
[ -S path_1 ] - validates whether it is a Socket file
Here is the way to create a socket file
[root@discoveringsystems conditionals]# socat unix-listen:test_socket_file.sock,fork /dev/null &
[1] 67206
I am using the above command to create a unix domain stream based socket file.
“Test_socket_file.sock” is the name of the socket file
“fork” option keeps the socat continues to run , otherwise it will exit after it handled a connection
“/dev/null” path is used as a destination to divert any incoming inputs , as any redirection to that gets deleted silently
“&” runs a command as a background job
We were able to see the socket file is created by the system
[root@discoveringsystems conditionals]# ls -l | grep -i socket
srwxr-xr-x. 1 root root 0 Feb 27 12:43 test_socket_file.sock
Stat command also confirms that it is a socket file
[root@discoveringsystems conditionals]# stat test_socket_file.sock
File: ‘test_socket_file.sock’
Size: 0 Blocks: 0 IO Block: 4096 socket
Device: fd00h/64768d Inode: 35344324 Links: 1
Access: (0755/srwxr-xr-x) Uid: ( 0/ root) Gid: ( 0/ root)
Context: unconfined_u:object_r:admin_home_t:s0
Access: 2023-02-27 12:43:44.448571786 -0500
Modify: 2023-02-27 12:43:44.448571786 -0500
Change: 2023-02-27 12:43:44.448571786 -0500
Birth: -
Here is a script to verify that
[root@discoveringsystems conditionals]# cat bash_script_files
#!/bin/bash
path_1="test_socket_file.sock"
if [ -S $path_1 ]; then
echo "$path_1 is a socket file "
else
echo "$path_1 is not a socket file "
fi
[root@discoveringsystems conditionals]# ./bash_script_files
test_socket_file.sock is a socket file
Using Bash conditionals to validate whether a file is a named pipe file
Before starting with the conditionals for named pipe file , I would like to explain how the named pipe works
Named pipe files can be created using the following command and will show up as type named files when we use the ls -l command . For the named pipe file we will see the “p” while using ls command
[root@discoveringsystems conditionals]# mkfifo test-pipe
[root@discoveringsystems conditionals]# ls -ltrh | grep -i pipe
prw-r--r--. 1 root root 0 Mar 20 11:41 test-pipe
Named pipe file works very similar to the regular Pipe seen in the linux systems , but named pipe exists as a file and can be used between any two processes , one to write to it and another one on the other side of the pipe to read it. In a regular pipe it is being used between a parent and the child process.
Since it operates in First In First out Model , so we will be sending some inputs on the pipe on one end and hit return and you will see the process stays until there is another process opens the file on another end to read it , once the content is read the pipe is empty again. Named pipe file stores the contents in the virtual memory and does not use the disk space
Example : From one end , i echoed some input into the named pipe
[root@discoveringsystems conditionals]# echo " i am sending some data into pipe" > test-pipe
From another terminal or another process , I need to read it else if the echo won’t complete. While this happens we can see no disk space is used by it and now i read the detail from another terminal through the cat to empty the pipe
[root@discoveringsystems conditionals]# ls -ltrh test-pipe
prw-r--r--. 1 root root 0 Mar 20 11:48 test-pipe
[root@discoveringsystems conditionals]# cat test-pipe
i am sending some data into pipe
As soon as i did this , on the other terminal the command i started stopped on its own after emptying the pipe
[root@discoveringsystems conditionals]# echo " i am sending some data into pipe" > test-pipe
[root@discoveringsystems conditionals]#
Bash conditionals have ways to detect whether a file is a named pipe using the following syntax
[ -p path_to_file ] - validates whether a file is a named pipe
Here is an example Code
[root@discoveringsystems conditionals]# cat bash_script_files
#!/bin/bash
path_1="test-pipe"
if [ -p $path_1 ]; then
echo "$path_1 is a named pipe file "
else
echo "$path_1 is not a named pipe file "
fi
[root@discoveringsystems conditionals]# ./bash_script_files
test-pipe is a named pipe file
Other Bash conditionals available for the files
Following are few other bash conditionals which can used for different use cases as described
[ -g path_of_file ] - validates whether a sgid bit is set on a directory file . When this bit is set for a directory , the files created under the directory inherits the group of the directory
[ -G path_of_file ] - Effective group id is the group id of the user executing the script. This validates whether the file is owned by the effective group , so that we can change the group if required
[ -N path_of_file ] - Validates whether the file was modified after the last read
[ path_of_file_1 -nt path_of_file_2 ] - Validates whether file 1 is newer or changed recently when compared to file 2 . Also can be used to validate whether file 1 is present , but the file 2 doesn’t