Shell Scripting – Operators
Hello Everyone
Welcome to CloudAffaire and this is Debjeet.
In the last blog post, we have discussed shell variables.
https://cloudaffaire.com/shell-scripting-shell-variables/
In this blog post, we will discuss shell operators. Like any other programming language, shell also supports operator. Operators are constructs which behave generally like functions, but which differ syntactically or semantically from usual functions. Common simple examples include arithmetic (addition with +), comparison (with >), and logical operations (such as AND or &&) etc. Operator tells interpreter/compiler to perform some mathematical or logical construct on the operands.
Shell Scripting – Operators:
Arithmetic Operators:
Arithmetic operators are used to perform arithmetic operations like the addition of two numbers. Shell only supports arithmetic operations on integers, but you can still perform the floating-point calculation using tools like bc. Below are the arithmetic operators supported by shell –
Symbol | Operation | Example |
+ | addition | 20 + 3 = 23 |
– | subtraction | 20 – 3 = 17 |
* | multiplication | 20 * 3 = 60 |
/ | division | 20 / 3 = 6 (by default only returns integer) |
% | modulus | 20 % 3 = 2 |
x++ | post-increment | 20++ (returns 21 in next run) |
x– | post-decrement | 20– (returns 19 in next run) |
++x | pre-increment | ++20 (returns 21 in current run) |
–x | pre-decrement | –20 (returns 19 in current run) |
+= | increment by constant value | 20 +=10 (returns 30) |
-= | decrement by constant value | 20 -=10 (returns 10) |
*= | multiplication by constant value | 20*=3 (returns 60) |
/= | division by constant value | 20/=4 (returns 5) |
%= | mod by constant value | 20%=3 (returns 2) |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
################################# ## Shell Scripting | Operators ## ################################# ## Prerequisites: One Unix/Linux/POSIX-compliant operating system with bash shell ## -------------------- ## Arithmetic Operators ## -------------------- ## Different way's to perform artithmetic operations in shell a=20 ## variable declaretion b=3 echo $(($a+$b)) ## using $(()) echo $((20+3)) echo `expr $a + $b` ## using expr echo `expr 20 + 3` echo $[ $a + $b ] ## using [] echo $[ 5 + 6 ] let sum=$a+$b; echo $sum ## using let let sum=20+3; echo $sum echo "$a + $b" | bc ## using bc echo "20 + 3" | bc ((sum=$a+$b)); echo $sum ## using (()) ((sum=20+3)); echo $sum ## Different arithmetic operators a=20 ## Assignmet operator (=) b=3 c=7 echo $(($a+$b)) ## Addition (+), returns 23 echo $((c+=3)) ## Increment by a constant value (+=), returns 10 echo $((c++)); echo $c ## Post Increment by 1 (i++), returns 11 echo $((++c)) ## Pre Increment by 1 (++i), returns 12 echo $(($a-$b)) ## Substraction (-), returns 17 echo $((c-=3)) ## Decrement by a constant value (-=), returns 9 echo $((c--)); echo $c ## Post Decrement by 1 (i--), returns 8 echo $((--c)) ## Pre Decrement by 1 (--i), returns 7 echo $(($a*$b)) ## Multiplication (*), returns 60 echo $((c*=10)) ## Multiply by a constant value (*=), returns 70 echo $(($b**2)) ## Exponential (**), returns 9 echo $(($a/$b)) ## Division (/), returns 6 echo "$a/$b" | bc -l ## Division (/), returns 6.66666666666666 echo $((c/=10)) ## Division by a constant value (/=), returns 7 echo $(($a%$b)) ## Modulo or mod (%), returns the remainder of division 2 in this case n=100; echo $((n%=19)) ## Assign mod to variable (%=), returns 5 |
Relational Operators:
The relational operator is used to compare two values. Shell supports Equality, Non-equality, Less Than, and Greater Than relational operators. -eq, -nq, -lt, -gt, -le, -ge are only supported for integer comparisons.
Symbol | Operation | Example |
= == -eq | Equality | 20 -eq 20 returns true, “cat” == “cat” returns true |
!= -nq | Non-Equality | 20 -nq 10 returns true, “dog” != “cat” returns true |
> >= -gt -ge | Greater Than & Greater Than Equals To | “cat” > “dog” returns true, 20 -gt 10 returns true |
< <= -lt -le | Less Than & Less Than Equals To | “dog” < “cat” returns true, 10 -lt 20 returns true |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 |
## -------------------- ## Relational Operators ## -------------------- ## Different ways to use relational operators in shell a=20 ## Assignment (=) if [ $a == 20 ]; then echo "i m true"; fi ## Using if [] if [[ $a == 20 ]]; then echo "i m true"; fi ## Using if [[]] if (( $a == 20 )); then echo "i m true"; fi ## Using if (()) if test $a == 20; then echo "i m true"; fi ## Using if test [ $a == 20 ] && echo "i m true" ## Using [] [[ $a == 20 ]] && echo "i m true" ## Using [[]] (( $a == 20 )) && echo "i m true" ## Using (()) test $a == 20 && echo "i m true" ## Using test ## Different relational operators ## Equality (= == eq) ## eq should only be used with integer data type a=20 ## = also represent assignment operator b="deb" if [ $a == 20 ]; then echo "i m true"; fi ## Bash specific with numeric data type if [ $a = 20 ]; then echo "i m true"; fi ## POSIX sh with numeric data type if [ $b == "deb" ]; then echo "i m true"; fi ## Bash specific with string data type if [ $b = "deb" ]; then echo "i m true"; fi ## Bash specific with string data type if [ $a -eq 20 ]; then echo "i m true"; fi ## only works with integer ## Not Equality (!= -ne) a=20 b="deb" if [ $a != 10 ]; then echo "i m true"; fi ## compares integer if [ $b != "cat" ]; then echo "i m true"; fi ## compares string if [ $a -ne 10 ]; then echo "i m true"; fi ## only works with integer ## Greater than (> >= -gt -ge) a=20 b="cat" if [ $a > 10 ]; then echo "i m true"; fi ## compares integer for greater than if [ $a >= 20 ]; then echo "i m true"; fi ## compares integer for greater than equals to if [ $b > "dog" ]; then echo "i m true"; fi ## compares string in alfhabetic order if [ $b >= "cats" ]; then echo "i m true"; fi ## compares string in alfhabetic order if [ $a -gt 10 ]; then echo "i m true"; fi ## only works with integer if [ $a -ge 20 ]; then echo "i m true"; fi ## only works with integer ## Less than (< <= -lt -le) a=20 b="cat" if [ $a < 100 ]; then echo "i m true"; fi ## compares integer for less than if [ $a <= 20 ]; then echo "i m true"; fi ## compares integer for less than equals to if [ $b < "dog" ]; then echo "i m true"; fi ## compares string in alfhabetic order if [ $b <= "cats" ]; then echo "i m true"; fi ## compares string in alfhabetic order if [ $a -lt 100 ]; then echo "i m true"; fi ## only works with integer if [ $a -le 20 ]; then echo "i m true"; fi ## only works with integer |
Boolean Or Logical Operators:
Boolean or Logical operators are used to perform AND, OR, and Not logical operations between two or more operands.
Symbol | Operation | Example |
&& -a | AND | (condition) && (condition) returns true if both conditions are true |
|| -o | OR | (condition) || (condition) returns true if anyone is true |
! | NOT | !(condition) returns true if condition is false and vice versa |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
## ---------------------------- ## Boolean or Logical Operators ## ---------------------------- ## Different ways to use boolean operators a=30; b=20; c=10 if [[ $a -gt $b && $a -gt $c ]]; then echo $a; fi if [[ ($a -gt $b && $a -gt $c) ]]; then echo $a; fi if [ $a -gt $b ] && [ $a -gt $c ]; then echo $a; fi if [ $a -gt $b -a $a -gt $c ]; then echo $a; fi if [ ( $a -gt $b -a $a -gt $c ) ]; then echo $a; fi if (($a-gt$b&$a-gt$c)); then echo $a; fi if (($a-gt$b&&$a-gt$c)); then echo $a; fi ## Different Boolean Operators ## Logical AND (& && -a) ## returns true if both side is true a=30; b=20; c=10 if [[ $a -gt $b && $a -gt $c ]]; then echo $a; fi if [ $a -gt $b -a $a -gt $c ]; then echo $a; fi if (($a-gt$b&$a-gt$c)); then echo $a; fi ## Logical OR (|| -o) ## returns true if any one is true a=true; b=false if [[ $a == "false" || $b == "false" ]]; then echo "atleast one fasle"; fi if [ $a == "false" -o $b == "false" ]; then echo "atleast one fasle"; fi ## Logical NOT (!) ## returns true if false or false if true a=true; b=false if [[ ! $a == "false" ]]; then echo "$a is true"; fi if [[ ! $b == "true" ]]; then echo "$b is false"; fi |
Bitwise Operators:
A bitwise operator is an operator used to perform bitwise operations on bit patterns.
Symbol | Operation | Example |
& | Bitwise AND | Performs AND operation on every bit of operands Example: 00001010 & 00001000 = 00001000 |
| | Bitwise OR | Performs OR operation on every bit of operands Example: 00001010 | 00001000 = 00001010 |
^ | Bitwise XOR | Performs XOR operation on every bit of operands Example: 00001010 ^ 00001000 = 00000010 |
~ | Bitwise NOT | Performs NOT operation on every bit of operand Example: ~00001010 = 11110101 |
>> | Bitwise Right Shift | Shift bits to right and adds ‘0’s on left Example: >>00001010 = 00000010 |
<< | Bitwise Left Shift | Shift bits to left and add ‘0’ on left Example: <<00001010 = 00101000 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 |
## ----------------- ## Bitwise Operators ## ----------------- dectobin=({0..1}{0..1}{0..1}{0..1}{0..1}{0..1}{0..1}{0..1}) ## Creates an arry of decimal numbers echo ${dectobin[10]} ## 10 ==> 1010 ## Bitwise AND (&) ## Performs AND operation on every bit and produces result a=10;b=8 BitwiseAND=$(($a&$b)) echo "${dectobin[$a]} BitwiseAND ${dectobin[$b]} ==> ${dectobin[$BitwiseAND]}" ## in binary echo "$a BitwiseAND $b ==> $BitwiseAND" ## in decimal ## Bitwise AND (&) == (1 & 1 ==> 1, 1 & 0 ==> 0, 0 & 1 ==> 0, 0 & 0 ==> 0) ## 00001010 ==> 10 ## 00001000 ==> 8 ##------------------ ## 00001000 ==> 8 ## Bitwise OR (|) ## Performs OR operation on every bit and produces result a=10;b=8 BitwiseOR=$(($a|$b)) echo "${dectobin[$a]} BitwiseOR ${dectobin[$b]} ==> ${dectobin[$BitwiseOR]}" ## in binary echo "$a BitwiseOR $b ==> $BitwiseOR" ## in decimal ## Bitwise OR (|) == (1 | 1 ==> 1, 1 | 0 ==> 1, 0 | 1 ==> 1, 0 | 0 ==> 0) ## 00001010 ==> 10 ## 00001000 ==> 8 ##------------------ ## 00001010 ==> 10 ## Bitwise XOR (^) ## Performs XOR operation on every bit and produces result a=10;b=8 BitwiseXOR=$(($a^$b)) echo "${dectobin[$a]} BitwiseXOR ${dectobin[$b]} ==> ${dectobin[$BitwiseXOR]}" ## in binary echo "$a BitwiseXOR $b ==> $BitwiseXOR" ## in decimal ## Bitwise XOR (^) == (1 ^ 1 ==> 0, 1 ^ 0 ==> 1, 0 ^ 1 ==> 1, 0 ^ 0 ==> 0) ## 00001010 ==> 10 ## 00001000 ==> 8 ##------------------ ## 00000010 ==> 2 ## Bitwise NOT (~) ## Performs NOT (Inverts all the bits) operation on every bit and produces result a=10 BitwiseNOT=$((~$a)) echo "BitwiseNOT Of ${dectobin[$a]} ==> ${dectobin[$BitwiseNOT]}" ## in binary echo "BitwiseNOT $a ==> $BitwiseNOT" ## in decimal returns negetive due to two's complement arithmetic ## Bitwise NOT (~) == (~1 ==> 0, ~0 ==> 1) ## 00001010 ==> 10 ## NOT ##------------------- ## 11110101 ==> -11 (should be 245 but returns -11 due to two's complement arithmetic) ## Bitwise Right Shift (>>) ## Shift bits to right and adds '0's on left (Divide by 2 operation). a=10 BitwiseRightShift=$(($a>>2)) echo "2 BitwiseRightShift Of ${dectobin[$a]} ==> ${dectobin[$BitwiseRightShift]}" ## in binary echo "2 BitwiseRightShift $a ==> $BitwiseRightShift" ## in decimal ## Bitwise Right Shift (>>) ## 00001010 ==> 10 ## Bitwise Right Shift by 2 ##------------------ ## 00000010 ==> 2 ## Bitwise Left Shift (<<) ## Shift bits to left and adds '0's on left (Multiply by 2 operation). a=10 BitwiseLeftShift=$(($a<<2)) echo "2 BitwiseLeftShift Of ${dectobin[$a]} ==> ${dectobin[$BitwiseLeftShift]}" ## in binary echo "2 BitwiseLeftShift $a ==> $BitwiseLeftShift" ## in decimal ## Bitwise Right Shift (<<) ## 00001010 ==> 10 ## Bitwise Left Shift by 2 ##------------------ ## 00101000 ==> 40 |
File Operators:
File operators are a special set of operators to perform checks on files and directory.
Symbol | Operation | Example |
-e | Checks if file exists | if [ -e $file ] returns true if file exist |
-d | Checks if directory exist | if [ -d $directory ] returns true if directory exist |
-s | Checks if file size greater than zero | if [ -s $file ] returns true if file has data |
-x | Checks if file has execute permission | if [ -x $file ] returns true if file has execute permission |
-w | Checks if file has write permission | if [ -w $file ] returns true if file has write permission |
-r | Checks if file has read permission | if [ -r $file ] returns true if file has read permission |
-b | Checks if file type is block device | if [ -b $file ] returns true if file type is block device |
-c | Checks if file type is charecter device | if [ -c $file ] returns true if file type is charecter device |
-h | Checks if file type is symbolic link | if [ -h $file ] returns true if file type is symbolic link |
-p | Checks if file type is pipe | if [ -p $file ] returns true if file type is pipe |
-S | Checks if file type is socket | if [ -S $file ] returns true if file type is socket |
-O | Checks if you are the owner of the file | if [ -O $file ] returns true if you are the owner of the file |
-G | Checks if group-id of the file is same as yours | if [ -G $file ] returns true if you and file owner has same group |
-N | Checks if file has been modified since last read | if [ -N $file ] returns true if file has been modified since last read |
-k | Checks if sticky bit is set on the file | if [ -k $file ] returns true if sticky bit is set on the file |
-u | Checks if sudi is set on the file | if [ -u $file ] returns true if suid is set on the file |
-g | Checks if sgdi is set on the file | if [ -g $file ] returns true if sgid is set on the file |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 |
## ------------- ## File Operator ## ------------- ## Create some files and directory and define them in variable mkdir -p mydir/mydir1 && cd mydir mkfifo pipe && touch myfile python -c "import socket as s; sock = s.socket(s.AF_UNIX); sock.bind('socket')" chmod 1777 mydir1 file=myfile folder=mydir1 myblockdevice=/dev/xvda mychardevice=/dev/null mysymlink=/dev/fd mypipe=pipe mysocket=socket ## -e ==> Checks if file exists; is true even if file is a directory but exists if [ -e $file ]; then echo "$file exist"; fi ## returns myfile exist if [ -e $folder ]; then echo "$folder exist"; fi ## -d ==> Checks if directory exist, returns true if exist if [ -d $folder ]; then echo "$folder exist"; fi ## returns mydir1 exist ## -s ==> Checks if file has size greater than 0; returns true if size > 0 if [ -s $file ]; then echo "$file has data"; fi ## returns nothing as the file is empty echo "hellow world" > myfile ## enter some data if [ -s $file ]; then echo "$file has data"; fi ## returns myfile has data ## -x ==> Checks if file is executable; returns true if executable if [ -x $file ]; then echo "$file is executable"; fi ## returns nothing as the file is not executable chmod +x myfile if [ -x $file ]; then echo "$file is executable"; fi ## returns file is executable ## -w ==> Checks if file is writable; returns true if write access present if [ -w $file ]; then echo "$file is writable"; fi ## returns myfile is writable ## -r ==> Checks if file is readable; returns true if read access present if [ -r $file ]; then echo "$file is readable"; fi ## returns myfile is readable ## -b ==> Checks if file is block device, returns true if block device if [ -b $myblockdevice ]; then echo "$myblockdevice is a block device"; fi ## returns /dev/xvda is a block device ## -c ==> Checks if file is charecter device, returns true if charecter device if [ -c $mychardevice ]; then echo "$mychardevice is a charecter device"; fi ## returns /dev/null is a charecter device ## -h ==> Checks if file is a symbolic link, returns true if symbolic link if [ -h $mysymlink ]; then echo "$mysymlink is a symbolic link"; fi ## returns /dev/fd is a symbolic link ## -p ==> Checks if file is a pipe, returns true if pipe if [ -p $mypipe ]; then echo "$mypipe is a pipe file"; fi ## returns pipe is a pipe file ## -S ==> Checks if file is a socket, returns true if socket if [ -S $mysocket ]; then echo "$mysocket is a socket file"; fi ## returns socket is a socket file ## -O ==> Checks if you are the owner of the file, returns true if yes if [ -O $file ]; then echo "$file is owned by me"; fi ## returns myfile is owned by me ## -G ==> Checks if group-id of the file is same as yours, returns true if yes if [ -G $file ]; then echo "$file group-id is same as mine"; fi ## returns myfile group-id is same as mine ## -N ==> Checks if file has been modified since it was last read if [ -N $file ]; then echo "$file has been modified since last read"; fi ## returns myfile has been modified since last read ## -k ==> Checks if sticky bit set, returns true is set if [ -k $folder ]; then echo "$folder has sticky bit set"; fi ## returns mydir1 has sticky bit set ## -u ==> Checks if set-user-id (suid) flag set on file, returns true if set. chmod u+s myfile ## set suid if [ -u $file ]; then echo "$file has suid set"; fi ## returns myfile has suid set ## -g ==> Checks if set-group-id (sgid) flag set on file or directory, returns true if set chmod g+s myfile ## set sgid if [ -g $file ]; then echo "$file has sgid set"; fi ## returns myfile has sgid set cd .. && rm -rf mydir |
Below are some additional operators that you can use in bash.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
## --------------- ## Other Operators ## --------------- ## [ $string ] ==> Checks if the string is non empty, returns true if non-empty a="deb" ## string has value if [ $a ]; then echo "string $a is not empty" else echo "string $a is empty"; fi ## -n ==> Checks if the given string is non zero length, returns true if size non-zero a="deb" ## string has value if [ -n $a ]; then echo "string $a is non zero length" else echo "string $a is of zero length"; fi ## -z ==> Checks if the given string is zero length, returns true if size zero a="deb" ## string has value if [ -z $a ]; then echo "string $a is zero length" else echo "string $a is non zero length"; fi ## condition ? true : false ==> Ternary or conditional operator a=10 b=$(( a > 5 ? 100 : 200 )); echo $b ## returns 100 b=$(( a > 20 ? 100 : 200 )); echo $b ## returns 200 |
Hope you have enjoyed this article. In the next blog post, we will discuss looping in bash.