Complete Guide to Bash Operators

Introduction to Bash Operators

Operators in Bash are symbols that perform specific operations on operands (values or variables). Understanding operators is crucial for writing effective shell scripts, as they enable arithmetic operations, comparisons, logical decisions, and string manipulations.

Key Concepts

  • Arithmetic Operators: Perform mathematical calculations
  • Comparison Operators: Compare values (strings and numbers)
  • Logical Operators: Combine conditions for decision making
  • Assignment Operators: Assign and modify values
  • Bitwise Operators: Manipulate bits
  • String Operators: Work with text data
  • File Test Operators: Check file properties

1. Arithmetic Operators

Basic Arithmetic

#!/bin/bash
# Basic arithmetic operators
a=10
b=3
# Addition
sum=$((a + b))
echo "a + b = $sum"           # 13
# Subtraction
diff=$((a - b))
echo "a - b = $diff"          # 7
# Multiplication
prod=$((a * b))
echo "a * b = $prod"          # 30
# Division (integer)
div=$((a / b))
echo "a / b = $div"           # 3 (truncates)
# Modulo (remainder)
mod=$((a % b))
echo "a % b = $mod"           # 1
# Exponentiation
power=$((a ** b))
echo "a ** b = $power"        # 1000 (10^3)
# Using expr command (old style)
result=$(expr $a + $b)
echo "expr: $result"          # 13
# Using let command
let result=a+b
echo "let: $result"           # 13

Increment and Decrement

#!/bin/bash
x=5
# Post-increment
echo $((x++))                  # 5 (then x becomes 6)
echo "x = $x"                  # 6
# Pre-increment
echo $((++x))                  # 7 (x becomes 7, then printed)
echo "x = $x"                  # 7
# Post-decrement
echo $((x--))                  # 7 (then x becomes 6)
echo "x = $x"                  # 6
# Pre-decrement
echo $((--x))                  # 5 (x becomes 5, then printed)
echo "x = $x"                  # 5
# Using let for increment/decrement
let x++                        # Post-increment
let ++x                        # Pre-increment
let x--                        # Post-decrement
let --x                        # Pre-decrement

Compound Assignment

#!/bin/bash
x=10
# Add and assign
((x += 5))
echo "x += 5 -> $x"           # 15
# Subtract and assign
((x -= 3))
echo "x -= 3 -> $x"           # 12
# Multiply and assign
((x *= 2))
echo "x *= 2 -> $x"           # 24
# Divide and assign
((x /= 4))
echo "x /= 4 -> $x"           # 6
# Modulo and assign
((x %= 4))
echo "x %= 4 -> $x"           # 2
# Using let for compound assignment
let "x += 5"
let "x -= 3"
let "x *= 2"
let "x /= 4"
let "x %= 4"

Floating Point Arithmetic

#!/bin/bash
# Bash doesn't support floating point natively
# Use bc (basic calculator) for floating point
a=10.5
b=3.2
# Addition with bc
result=$(echo "$a + $b" | bc)
echo "$a + $b = $result"      # 13.7
# Division with scale (decimal places)
result=$(echo "scale=2; $a / $b" | bc)
echo "$a / $b = $result"      # 3.28
# More complex calculations
result=$(echo "scale=3; sqrt($a)" | bc)
echo "sqrt($a) = $result"     # 3.240
# Using bc for comparisons
if (( $(echo "$a > $b" | bc) )); then
echo "$a is greater than $b"
fi
# Alternative: use awk
result=$(awk "BEGIN {print $a / $b}")
echo "awk division: $result"

2. Comparison Operators

Integer Comparison

#!/bin/bash
a=10
b=5
c=10
# Equal
if [ $a -eq $c ]; then
echo "$a equals $c"       # 10 equals 10
fi
# Not equal
if [ $a -ne $b ]; then
echo "$a not equal $b"    # 10 not equal 5
fi
# Greater than
if [ $a -gt $b ]; then
echo "$a greater than $b" # 10 greater than 5
fi
# Less than
if [ $b -lt $a ]; then
echo "$b less than $a"    # 5 less than 10
fi
# Greater than or equal
if [ $a -ge $c ]; then
echo "$a >= $c"           # 10 >= 10
fi
# Less than or equal
if [ $b -le $c ]; then
echo "$b <= $c"           # 5 <= 10
fi
# Using double parentheses (preferred for integers)
if (( a == c )); then
echo "$a == $c"
fi
if (( a != b )); then
echo "$a != $b"
fi
if (( a > b )); then
echo "$a > $b"
fi
if (( a < b )); then
echo "$a < $b"
fi
if (( a >= c )); then
echo "$a >= $c"
fi
if (( a <= c )); then
echo "$a <= $c"
fi

String Comparison

#!/bin/bash
str1="hello"
str2="world"
str3="hello"
empty=""
# Equal
if [ "$str1" = "$str3" ]; then
echo "$str1 equals $str3"      # hello equals hello
fi
# Alternative syntax
if [[ "$str1" == "$str3" ]]; then
echo "$str1 == $str3"
fi
# Not equal
if [ "$str1" != "$str2" ]; then
echo "$str1 not equal $str2"   # hello not equal world
fi
# Greater than (lexicographic)
if [[ "$str2" > "$str1" ]]; then
echo "$str2 > $str1"           # world > hello
fi
# Less than (lexicographic)
if [[ "$str1" < "$str2" ]]; then
echo "$str1 < $str2"           # hello < world
fi
# Check if string is empty
if [ -z "$empty" ]; then
echo "String is empty"
fi
# Check if string is not empty
if [ -n "$str1" ]; then
echo "String is not empty"
fi
# Pattern matching
if [[ "$str1" == h* ]]; then
echo "$str1 starts with h"     # hello starts with h
fi
if [[ "$str1" == *lo ]]; then
echo "$str1 ends with lo"      # hello ends with lo
fi
if [[ "$str1" == *ell* ]]; then
echo "$str1 contains ell"      # hello contains ell
fi

3. Logical Operators

AND Operations

#!/bin/bash
a=10
b=5
c=20
# Logical AND with test command (old style)
if [ $a -gt $b -a $a -lt $c ]; then
echo "$a is between $b and $c"   # 10 is between 5 and 20
fi
# Logical AND with double brackets (preferred)
if [[ $a -gt $b && $a -lt $c ]]; then
echo "$a is between $b and $c"
fi
# Using double parentheses
if (( a > b && a < c )); then
echo "$a is between $b and $c"
fi
# Multiple conditions
name="John"
age=25
city="NYC"
if [[ "$name" == "John" && $age -gt 18 && "$city" == "NYC" ]]; then
echo "John from NYC is an adult"
fi
# Short-circuit evaluation (second condition only evaluated if first true)
if [[ -f "$file" && $(wc -l < "$file") -gt 0 ]]; then
echo "File exists and is not empty"
fi

OR Operations

#!/bin/bash
day=$(date +%A)
# Logical OR with test command (old style)
if [ "$day" = "Saturday" -o "$day" = "Sunday" ]; then
echo "It's weekend!"
fi
# Logical OR with double brackets (preferred)
if [[ "$day" == "Saturday" || "$day" == "Sunday" ]]; then
echo "It's weekend!"
fi
# Using double parentheses
x=5
if (( x == 5 || x == 10 )); then
echo "x is either 5 or 10"
fi
# Multiple conditions
error_code=$1
if [[ $error_code -eq 404 || $error_code -eq 500 || $error_code -eq 503 ]]; then
echo "Common HTTP error"
fi
# OR with default value
name=${1:-"Guest"}          # Use $1 if set, otherwise "Guest"
echo "Hello, $name"

NOT Operations

#!/bin/bash
# Logical NOT with test command
if [ ! -f "$file" ]; then
echo "File does not exist"
fi
# NOT with double brackets
if [[ ! -f "$file" ]]; then
echo "File does not exist"
fi
# NOT with double parentheses
x=5
if (( ! (x > 10) )); then
echo "x is not greater than 10"    # x is not greater than 10
fi
# Combining NOT with AND/OR
if [[ ! -f "$file" || ! -r "$file" ]]; then
echo "File either doesn't exist or isn't readable"
fi
# Check if variable is not set
if [ -z "${var+x}" ]; then
echo "var is unset"
fi
# Opposite condition
if ! command -v git >/dev/null 2>&1; then
echo "git is not installed"
fi

Combining Logical Operators

#!/bin/bash
# Complex conditions
age=25
has_license=true
has_insurance=true
if [[ $age -ge 18 && $has_license == true && $has_insurance == true ]]; then
echo "Can drive legally"
fi
# Nested conditions with grouping
if [[ ($age -ge 18 && $has_license == true) || ($age -ge 16 && $has_permit == true) ]]; then
echo "Can operate vehicle"
fi
# Truth table for logical operators
true && true    # true
true && false   # false
false && true   # false
false && false  # false
true || true    # true
true || false   # true
false || true   # true
false || false  # false
!true           # false
!false          # true

4. Assignment Operators

Basic Assignment

#!/bin/bash
# Simple assignment
name="John"
age=25
echo "Name: $name, Age: $age"
# Multiple assignments (same line)
a=5 b=10 c=15
echo "a=$a, b=$b, c=$c"
# Assignment with command substitution
files=$(ls -la)
current_date=$(date)
echo "Date: $current_date"
# Assignment with arithmetic
x=$((5 + 3))
y=$((x * 2))
# Read-only assignment
readonly PI=3.14159
# PI=3.14  # This would cause an error

Compound Assignment

#!/bin/bash
x=10
# All compound operators work with ((...))
((x += 5))      # x = x + 5
((x -= 3))      # x = x - 3
((x *= 2))      # x = x * 2
((x /= 4))      # x = x / 4
((x %= 3))      # x = x % 3
# Using let command
let "x += 5"
let "x -= 3"
let "x *= 2"
let "x /= 4"
let "x %= 3"
# Bitwise compound assignment
((x <<= 1))     # x = x << 1 (left shift)
((x >>= 1))     # x = x >> 1 (right shift)
((x &= 7))      # x = x & 7 (bitwise AND)
((x |= 8))      # x = x | 8 (bitwise OR)
((x ^= 3))      # x = x ^ 3 (bitwise XOR)

5. Bitwise Operators

Basic Bitwise Operations

#!/bin/bash
a=5   # 0101 in binary
b=3   # 0011 in binary
# Bitwise AND
result=$((a & b))
echo "$a & $b = $result"      # 1 (0001)
# Bitwise OR
result=$((a | b))
echo "$a | $b = $result"      # 7 (0111)
# Bitwise XOR
result=$((a ^ b))
echo "$a ^ $b = $result"      # 6 (0110)
# Bitwise NOT (complement)
result=$((~a))
echo "~$a = $result"          # -6 (two's complement)
# Left shift
result=$((a << 1))
echo "$a << 1 = $result"      # 10 (1010)
# Right shift
result=$((a >> 1))
echo "$a >> 1 = $result"      # 2 (0010)
# Practical examples
# Check if bit is set
bit=2
if (( (a & (1 << bit)) != 0 )); then
echo "Bit $bit is set in $a"
fi
# Set a bit
mask=$((1 << 1))
result=$((a | mask))
echo "Set bit 1 in $a: $result"
# Clear a bit
mask=$((1 << 2))
result=$((a & ~mask))
echo "Clear bit 2 in $a: $result"
# Toggle a bit
mask=$((1 << 0))
result=$((a ^ mask))
echo "Toggle bit 0 in $a: $result"

Bit Manipulation Examples

#!/bin/bash
# Power of 2 check
is_power_of_two() {
local n=$1
if (( n > 0 && (n & (n-1)) == 0 )); then
return 0
else
return 1
fi
}
for num in 1 2 3 4 16 31 64; do
if is_power_of_two $num; then
echo "$num is a power of 2"
fi
done
# Count set bits (population count)
count_bits() {
local n=$1
local count=0
while (( n )); do
((count += n & 1))
((n >>= 1))
done
echo $count
}
echo "Bits set in 13: $(count_bits 13)"    # 1101 -> 3 bits
# Swap two numbers without temporary variable
a=5
b=3
((a ^= b))
((b ^= a))
((a ^= b))
echo "After swap: a=$a, b=$b"              # a=3, b=5
# Check if numbers have opposite signs
x=5
y=-3
if (( (x ^ y) < 0 )); then
echo "$x and $y have opposite signs"
fi
# Get absolute value
abs() {
local n=$1
echo $(( (n ^ (n >> 31)) - (n >> 31) ))
}
echo "Absolute of -5: $(abs -5)"

6. String Operators

String Length and Substrings

#!/bin/bash
str="Hello World"
# String length
echo "Length: ${#str}"                     # 11
# Substring extraction
echo "${str:6}"                            # World (from position 6)
echo "${str:6:3}"                          # Wor (3 chars from pos 6)
echo "${str: -5}"                          # World (last 5 chars)
echo "${str: -5:3}"                        # Wor (3 chars from end)
# Substring removal (from beginning)
filename="archive.tar.gz"
echo "${filename#*.}"                      # tar.gz (remove shortest match)
echo "${filename##*.}"                     # gz (remove longest match)
# Substring removal (from end)
echo "${filename%.*}"                       # archive.tar (remove shortest from end)
echo "${filename%%.*}"                      # archive (remove longest from end)
# Replace
str="Hello Hello World"
echo "${str/Hello/Hi}"                      # Hi Hello World (first match)
echo "${str//Hello/Hi}"                      # Hi Hi World (all matches)
echo "${str/#Hello/Hi}"                      # Hi Hello World (beginning)
echo "${str/%World/Everyone}"                # Hello Hello Everyone (end)

Pattern Matching and Case Conversion

#!/bin/bash
# Pattern matching
filename="document.txt"
if [[ "$filename" == *.txt ]]; then
echo "Text file"
fi
if [[ "$filename" == doc* ]]; then
echo "Starts with 'doc'"
fi
# Case conversion (Bash 4+)
text="Hello World"
# Lowercase
echo "${text,,}"                           # hello world
echo "${text,}"                            # hello World (first char)
# Uppercase
echo "${text^^}"                           # HELLO WORLD
echo "${text^}"                            # Hello World (first char)
# Specific character conversion
echo "${text^^[aeiou]}"                    # HEllO WOrld
# Using tr command
echo "$text" | tr '[:lower:]' '[:upper:]'  # HELLO WORLD
echo "$text" | tr '[:upper:]' '[:lower:]'  # hello world

7. File Test Operators

File Type Tests

#!/bin/bash
file="/etc/passwd"
dir="/tmp"
link="/usr/bin/python"
special="/dev/null"
# File existence
if [ -e "$file" ]; then
echo "$file exists"
fi
# Regular file
if [ -f "$file" ]; then
echo "$file is a regular file"
fi
# Directory
if [ -d "$dir" ]; then
echo "$dir is a directory"
fi
# Symbolic link
if [ -L "$link" ]; then
echo "$link is a symbolic link"
fi
# Character special file
if [ -c "$special" ]; then
echo "$special is a character device"
fi
# Block special file
if [ -b "/dev/sda" ]; then
echo "/dev/sda is a block device"
fi
# Socket
if [ -S "/var/run/docker.sock" ]; then
echo "Docker socket exists"
fi
# Named pipe
if [ -p "/tmp/mypipe" ]; then
echo "Pipe exists"
fi

Permission Tests

#!/bin/bash
file="test.txt"
touch "$file"
# Readable
if [ -r "$file" ]; then
echo "$file is readable"
fi
# Writable
if [ -w "$file" ]; then
echo "$file is writable"
fi
# Executable
if [ -x "$file" ]; then
echo "$file is executable"
fi
# Setuid
if [ -u "/usr/bin/sudo" ]; then
echo "sudo has setuid bit"
fi
# Setgid
if [ -g "/usr/bin/wall" ]; then
echo "wall has setgid bit"
fi
# Sticky bit
if [ -k "/tmp" ]; then
echo "/tmp has sticky bit"
fi
# Non-empty file
echo "content" > "$file"
if [ -s "$file" ]; then
echo "$file is not empty"
fi
# Owned by effective user ID
if [ -O "$file" ]; then
echo "$file is owned by me"
fi
# Owned by effective group ID
if [ -G "$file" ]; then
echo "$file is owned by my group"
fi

File Comparison Tests

#!/bin/bash
file1="test1.txt"
file2="test2.txt"
echo "Hello" > "$file1"
echo "Hello" > "$file2"
# Same file (hard links)
if [ "$file1" -ef "$file2" ]; then
echo "Files are the same (hard links)"
else
echo "Files are different"
fi
# Newer modification time
touch "$file1"
sleep 2
touch "$file2"
if [ "$file2" -nt "$file1" ]; then
echo "$file2 is newer than $file1"
fi
# Older modification time
if [ "$file1" -ot "$file2" ]; then
echo "$file1 is older than $file2"
fi
# Cleanup
rm -f "$file1" "$file2"

8. Redirection Operators

Basic Redirection

#!/bin/bash
# Output redirection
echo "Hello World" > file.txt        # Overwrite
echo "Another line" >> file.txt      # Append
# Input redirection
sort < file.txt                      # Read from file
# Error redirection
command 2> error.txt                  # Redirect stderr only
command 2>> error.txt                 # Append stderr
# Both stdout and stderr
command &> output.txt                  # Redirect both
command &>> output.txt                 # Append both
# Separate streams
command > out.txt 2> err.txt          # stdout to out.txt, stderr to err.txt
# Discard output
command > /dev/null 2>&1              # Discard both stdout and stderr
# Here document (multiline input)
cat << EOF > file.txt
This is line 1
This is line 2
This is line 3
EOF
# Here string
grep "pattern" <<< "This is a test string"
# Process substitution
diff <(ls dir1) <(ls dir2)

File Descriptor Operations

#!/bin/bash
# Duplicate file descriptors
exec 3>&1                              # Save stdout to fd 3
exec 1> file.txt                       # Redirect stdout to file
echo "This goes to file"               
exec 1>&3                               # Restore stdout
exec 3>&-                               # Close fd 3
# Read from file descriptor
exec 3< input.txt                       # Open file for reading on fd 3
read line <&3                            # Read from fd 3
exec 3<&-                                # Close fd 3
# Custom file descriptors for append
exec 3>> log.txt                         # Open for append
echo "Log entry" >&3                     # Write to fd 3
exec 3>&-                                 # Close fd 3
# Using /dev/tcp for network operations
exec 3<>/dev/tcp/google.com/80           # Open TCP connection
echo -e "GET / HTTP/1.0\n\n" >&3         # Send HTTP request
cat <&3                                   # Read response
exec 3<&-                                 # Close connection

9. Test Operators

Special Test Constructs

#!/bin/bash
# Double brackets - extended test command
# Supports pattern matching and regex
if [[ "$name" == J* ]]; then
echo "Name starts with J"
fi
if [[ "$email" =~ ^[a-z]+@[a-z]+\.[a-z]+$ ]]; then
echo "Valid email format"
fi
# Double parentheses - arithmetic test
if (( a > b && a < c )); then
echo "a is between b and c"
fi
# Ternary-like operation
result=$(( a > b ? a : b ))              # Max of a and b
echo "Max: $result"
# Null coalescing (default value)
name=${1:-"Guest"}                        # Use $1 if set, else "Guest"
echo "Hello, $name"
# Alternate value
debug=${DEBUG:+1}                         # Set to 1 if DEBUG is set

Combined Test Examples

#!/bin/bash
# Complex file test
file="test.txt"
if [[ -f "$file" && -r "$file" && -w "$file" && -s "$file" ]]; then
echo "$file is a readable, writable, non-empty regular file"
fi
# String tests with default values
name=${1:-"Guest"}
if [[ -z "$name" || "$name" == "Guest" ]]; then
echo "No name provided, using default"
fi
# Numeric range checks
score=85
if (( score >= 90 )); then
grade="A"
elif (( score >= 80 )); then
grade="B"
elif (( score >= 70 )); then
grade="C"
else
grade="F"
fi
echo "Grade: $grade"
# Multiple condition check
if [[ -f "$file" ]] && command -v gzip >/dev/null; then
gzip "$file"
fi

10. Operator Precedence

Precedence Rules

#!/bin/bash
# Operator precedence (highest to lowest)
# 1. Post-increment/decrement: var++ var--
# 2. Pre-increment/decrement: ++var --var
# 3. Unary minus/plus: - + ! ~
# 4. Exponentiation: **
# 5. Multiplication/Division/Modulo: * / %
# 6. Addition/Subtraction: + -
# 7. Bitwise shifts: << >>
# 8. Relational: < <= > >=
# 9. Equality: == !=
# 10. Bitwise AND: &
# 11. Bitwise XOR: ^
# 12. Bitwise OR: |
# 13. Logical AND: &&
# 14. Logical OR: ||
# 15. Conditional: ? :
# 16. Assignment: = += -= *= /= %= &= ^= |= <<= >>=
# Examples
x=5
y=3
z=2
# Without parentheses (follows precedence)
result=$(( x + y * z ))
echo "x + y * z = $result"                 # 5 + (3 * 2) = 11
# With parentheses
result=$(( (x + y) * z ))
echo "(x + y) * z = $result"               # (5 + 3) * 2 = 16
# Complex expression
result=$(( x++ * --y + (z << 1) ))
echo "Complex result: $result"
# Logical operators
if [[ $x -gt 0 && $y -gt 0 || $z -gt 0 ]]; then
echo "AND has higher precedence than OR"
fi
# Equivalent with explicit parentheses
if [[ ($x -gt 0 && $y -gt 0) || $z -gt 0 ]]; then
echo "Same condition with parentheses"
fi

Using Parentheses for Clarity

#!/bin/bash
# Always use parentheses to make precedence clear
# Instead of:
if (( a > b && b > c || d == e ))
# Use:
if (( (a > b && b > c) || d == e ))
# Arithmetic with parentheses
result=$(( ( (a + b) * c ) / (d - e) ))
# Command grouping with parentheses (subshell)
(cd /tmp && ls -la)                       # Changes dir in subshell only
# Command grouping with braces (current shell)
{ cd /tmp && ls -la; }                     # Changes dir in current shell
# Brace expansion
echo {1..5}                                 # 1 2 3 4 5
echo {a,b,c}{1,2,3}                         # a1 a2 a3 b1 b2 b3 c1 c2 c3

11. Practical Examples

Calculator Function

#!/bin/bash
# Simple calculator using operators
calculator() {
local a=$1
local op=$2
local b=$3
case $op in
+)  echo $((a + b)) ;;
-)  echo $((a - b)) ;;
*)  echo $((a * b)) ;;
/)  
if (( b == 0 )); then
echo "Error: Division by zero"
return 1
fi
echo "scale=2; $a / $b" | bc
;;
%)  echo $((a % b)) ;;
^)  echo $((a ** b)) ;;
&)  echo $((a & b)) ;;
|)  echo $((a | b)) ;;
^^) echo $((a ^ b)) ;;
<<) echo $((a << b)) ;;
>>) echo $((a >> b)) ;;
*)  echo "Unknown operator: $op"
return 1 ;;
esac
}
# Usage
calculator 10 + 5
calculator 10 '*' 5    # Need to quote *
calculator 10 / 3
calculator 10 '**' 3

Input Validation

#!/bin/bash
# Validate numeric input
validate_number() {
local num=$1
# Check if it's a number
if [[ "$num" =~ ^-?[0-9]+$ ]]; then
return 0
else
return 1
fi
}
# Validate floating point
validate_float() {
local num=$1
if [[ "$num" =~ ^-?[0-9]*\.?[0-9]+$ ]]; then
return 0
else
return 1
fi
}
# Validate email
validate_email() {
local email=$1
if [[ "$email" =~ ^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$ ]]; then
return 0
else
return 1
fi
}
# Usage
read -p "Enter a number: " input
if validate_number "$input"; then
echo "Valid number"
else
echo "Invalid number"
fi

System Information Script

#!/bin/bash
# Using operators to gather system info
get_system_info() {
# Check if running as root
if [[ $EUID -eq 0 ]]; then
echo "Running as root"
else
echo "Running as regular user"
fi
# Check CPU architecture
arch=$(uname -m)
case "$arch" in
x86_64) echo "64-bit system" ;;
i*86)   echo "32-bit system" ;;
arm*)   echo "ARM system" ;;
*)      echo "Unknown architecture: $arch" ;;
esac
# Check memory (Linux)
if [[ -f /proc/meminfo ]]; then
total_mem=$(grep MemTotal /proc/meminfo | awk '{print $2}')
total_mem_mb=$((total_mem / 1024))
if (( total_mem_mb < 1024 )); then
echo "Low memory: ${total_mem_mb}MB"
elif (( total_mem_mb < 4096 )); then
echo "Moderate memory: ${total_mem_mb}MB"
else
echo "Plenty memory: ${total_mem_mb}MB"
fi
fi
# Check disk usage
usage=$(df / | tail -1 | awk '{print $5}' | sed 's/%//')
if (( usage > 90 )); then
echo "CRITICAL: Disk usage at ${usage}%"
elif (( usage > 75 )); then
echo "WARNING: Disk usage at ${usage}%"
else
echo "OK: Disk usage at ${usage}%"
fi
}

12. Operator Cheat Sheet

Quick Reference

# Arithmetic Operators
+   # Addition
-   # Subtraction
*   # Multiplication
/   # Division (integer)
%   # Modulo
**  # Exponentiation
++  # Increment
--  # Decrement
# Comparison Operators (Integer)
-eq # Equal
-ne # Not equal
-gt # Greater than
-ge # Greater or equal
-lt # Less than
-le # Less or equal
# Comparison Operators (String)
=   # Equal
==  # Equal ([[ ]])
!=  # Not equal
<   # Less than ([[ ]])
>   # Greater than ([[ ]])
-z  # Empty string
-n  # Non-empty string
# Logical Operators
&&  # Logical AND
||  # Logical OR
!   # Logical NOT
-a  # AND (test command)
-o  # OR (test command)
# Bitwise Operators
&   # Bitwise AND
|   # Bitwise OR
^   # Bitwise XOR
~   # Bitwise NOT
<<  # Left shift
>>  # Right shift
# Assignment Operators
=   # Simple assignment
+=  # Add and assign
-=  # Subtract and assign
*=  # Multiply and assign
/=  # Divide and assign
%=  # Modulo and assign
&=  # Bitwise AND and assign
|=  # Bitwise OR and assign
^=  # Bitwise XOR and assign
<<= # Left shift and assign
>>= # Right shift and assign
# File Test Operators
-e  # File exists
-f  # Regular file
-d  # Directory
-L  # Symbolic link
-r  # Readable
-w  # Writable
-x  # Executable
-s  # Non-zero size
-O  # Owned by user
-G  # Owned by group
-nt # Newer than
-ot # Older than
-ef # Same file
# Redirection Operators
>   # Redirect stdout (overwrite)
>>  # Redirect stdout (append)
<   # Redirect stdin
2>  # Redirect stderr
&>  # Redirect stdout and stderr
|   # Pipe
<<  # Here document
<<< # Here string

Conclusion

Key Takeaways

  1. Arithmetic Operators: Use $(( ... )) for integer math, bc for floating point
  2. Comparison: Use [[ ... ]] for strings and (( ... )) for numbers
  3. Logical Operators: Combine conditions with &&, ||, and !
  4. File Tests: Extensive operators for checking file properties
  5. String Operators: Powerful manipulation with pattern matching
  6. Bitwise Operators: Low-level bit manipulation
  7. Precedence: Understand and use parentheses for clarity

Best Practices

  • Use [[ ... ]] instead of [ ... ] for more features and fewer surprises
  • Use (( ... )) for arithmetic comparisons instead of -eq, -gt, etc.
  • Always quote variables in string comparisons: [[ "$var" == "value" ]]
  • Use parentheses to make operator precedence clear
  • Validate input before using in arithmetic operations
  • Use -z and -n for empty string checks
  • Combine file tests with logical operators for robust file handling

Common Pitfalls

# Pitfall 1: Spaces matter in test commands
[ $a = $b ]    # Correct spacing
[$a=$b]        # Wrong - will cause error
# Pitfall 2: Variable quoting
[[ $var == "" ]]     # Wrong - will fail if var contains spaces
[[ "$var" == "" ]]   # Correct
# Pitfall 3: Integer vs string comparison
if [[ $a > $b ]]     # String comparison (wrong for numbers)
if (( a > b ))       # Integer comparison (correct)
# Pitfall 4: Assignment vs comparison
if [ $a = $b ]       # Comparison (correct)
if [ $a = $b ]       # Assignment - no, this is also comparison in test
# Assignment is just: a=$b
# Pitfall 5: Missing then keyword
if [ condition ]     # Then must be on next line or with semicolon
then
commands
fi
# Or:
if [ condition ]; then
commands
fi

Mastering Bash operators is essential for writing effective shell scripts. Practice combining different operators to create powerful conditional logic and data manipulations.

Leave a Reply

Your email address will not be published. Required fields are marked *


Macro Nepal Helper