
Bash Functions: The Complete Guide
What is a Function in Bash?
A function in Bash is a block of reusable code that performs a specific task. Functions help you organize your scripts better, avoid repetition, and make your code modular and easier to maintain.
How to Define a Function?
There are two main ways to define functions in Bash:
Syntax 1:
$$
function function_name {
commands
}
$$
Syntax 2 (more portable):
$$
function_name() {
commands
}
$$
Both work the same way. The second style is more common and POSIX-compliant.
Example of a Simple Function
$$
greet() {
echo “Hello, welcome to Bash functions!”
}
$$
You can call the function simply by typing its name:
$$
greet
$$
Output:
$$
Hello, welcome to Bash functions!
$$
Why Use Functions?
Reuse: Write once, call multiple times.
Readability: Break complex scripts into manageable chunks.
Maintainability: Easier to debug and modify.
Parameters: Functions can accept arguments to customize behavior.
Passing Arguments to Functions
Functions can receive arguments just like scripts do. Inside a function:
$1
refers to the first argument,
$2
to the second,
and so on…
$#
is the number of arguments passed,
$@
or $*
refers to all arguments.
Example:
$$
greet() {
echo “Hello, $1! Welcome to Bash functions.”
}
greet “Alice”
$$
Output:
$$
Hello, Alice! Welcome to Bash functions.
$$
Returning Values from Functions
Bash functions don’t return values like in other programming languages. Instead:
You can use echo
or printf
inside the function to output the result.
The function’s exit status (0-255) can be set using the return
command, but this is usually for signaling success/failure, not data.
Example returning a value via echo:
$$
add() {
result=$(( $1 + $2 ))
echo $result
}
sum=$(add 3 5)
echo “Sum is $sum”
$$
Output:
$$
Sum is 8
$$
Example using return code:
$$
is_even() {
if (( $1 % 2 == 0 )); then
return 0 # true
else
return 1 # false
fi
}
is_even 4
echo $? # outputs 0 meaning true
$$
Local Variables in Functions
Variables declared inside functions are global by default. To restrict a variable’s scope to the function, use the local
keyword.
$$
my_func() {
local temp=“I am local”
echo “$temp”
}
my_func
echo “$temp” # empty because temp is local
$$
Function Examples
1. Function with no parameters
$$
print_date() {
echo “Today is $(date)”
}
print_date
$$
2. Function with parameters
$$
greet_person() {
echo “Hi $1, how are you today?”
}
greet_person “John”
$$
3. Function returning a computed value
$$
square() {
local num=$1
echo $((num * num))
}
result=$(square 7)
echo “Square of 7 is $result”
$$
Useful Tips
Always quote variables inside functions to avoid word splitting issues: "$1"
Use local
for temporary variables inside functions to avoid overwriting global variables.
Functions can call other functions.
Functions can be defined anywhere in your script but must be defined before you call them.
Real-World Use Cases of Bash Functions
1. Logging Messages
A function to log messages with timestamps and severity levels (INFO, WARNING, ERROR):
$$
log_message() {
local level=$1
shift
local message=“$*”
echo “$(date ‘+%Y-%m-%d %H:%M:%S’) [$level] $message”
}
Usage
log_message INFO “Script started”
log_message WARNING “Low disk space”
log_message ERROR “Failed to backup files”
$$
2. Checking If a File Exists
Reusable function to check if a file exists and is readable:
$$
file_exists() {
local file=$1
if [[ -f “$file” && -r “$file” ]]; then
return 0 # true
else
return 1 # false
fi
}
Usage
if file_exists “/etc/passwd”; then
echo “File exists and readable”
else
echo “File does not exist or is not readable”
fi
$$
3. Validating User Input
Function to ensure the user inputs a number between a range:
$$
get_number() {
local prompt=$1
local min=$2
local max=$3
local num
while true; do
read -p "$prompt ($min-$max): " num
if [[ "$num" =~ ^[0-9]+$ ]] && (( num >= min && num <= max )); then
echo "$num"
break
else
echo "Invalid input, try again."
fi
done
}
Usage
age=$(get_number “Enter your age” 1 120)
echo “Your age is $age”
$$
4. Downloading a File with Retry
Function that tries to download a file multiple times if it fails:
$$
download_file() {
local url=$1
local dest=$2
local retries=3
local count=0
while (( count < retries )); do
curl -o "$dest" "$url" && break
((count++))
echo "Retry $count/$retries..."
sleep 2
done
if (( count == retries )); then
echo "Failed to download file after $retries attempts"
return 1
fi
}
Usage
download_file “https://example.com/file.zip” “file.zip”
$$
5. Backup Function
Create timestamped backups of a given file or directory:
$$
backup() {
local source_path=$1
local backup_dir=$2
local timestamp=$(date +%Y%m%d_%H%M%S)
local base_name=$(basename “$source_path”)
mkdir -p "$backup_dir"
cp -r "$source_path" "$backup_dir/${base_name}_backup_$timestamp"
echo "Backup of $source_path created at $backup_dir/${base_name}_backup_$timestamp"
}
Usage
backup “/home/user/documents” “/home/user/backups”
$$
6. Parsing Command Line Arguments
Function to process flags/options:
$$
process_args() {
while [[ $# -gt 0 ]]; do
case $1 in
-h|–help)
echo “Usage: script.sh [-h|–help] [-v|–verbose]”
exit 0
;;
-v|–verbose)
VERBOSE=1
;;
*)
echo “Unknown option: $1”
exit 1
;;
esac
shift
done
}
Usage
VERBOSE=0
process_args “$@”
if [[ $VERBOSE -eq 1 ]]; then
echo “Verbose mode is ON”
fi
$$
7. Send Notification
Function to send a desktop or email notification (example uses notify-send
on Linux):
$$
notify() {
local message=$1
if command -v notify-send &> /dev/null; then
notify-send “Notification” “$message”
else
echo “notify-send not found, printing message instead:”
echo “$message”
fi
}
Usage
notify “Backup completed successfully!”
$$
8. Simple Calculator Function
Function that does basic arithmetic operations:
$$
calculate() {
local op=$1
local a=$2
local b=$3
case $op in
add) echo $((a + b)) ;;
sub) echo $((a - b)) ;;
mul) echo $((a * b)) ;;
div)
if [[ $b -eq 0 ]]; then
echo "Error: Division by zero"
return 1
else
echo $((a / b))
fi
;;
*)
echo "Invalid operation: $op"
return 1
;;
esac
}
#Usage
result=$(calculate add 10 20)
echo “Result: $result”
$$