Functions in Bash — Reusable Blocks of Code
Functions let you name and reuse blocks of commands. Learn how to define, call, and organise Bash functions to make your scripts modular and maintainable.
Functions are the building blocks of well-organised scripts. Instead of copying and pasting the same commands in multiple places, you define a function once and call it by name. This makes scripts shorter, easier to test, and easier to maintain.
Defining Functions
There are two syntax styles — both are equivalent:
# Style 1 — function keyword (more readable, preferred)
function greet {
echo "Hello, World!"
}
# Style 2 — POSIX-compatible (no keyword)
greet() {
echo "Hello, World!"
}
# Call it — just use the name
greetDefine before you call
Bash reads scripts top-to-bottom. A function must be defined before it's called. Common practice: define all functions near the top, then call them in a main function at the bottom.
Function Arguments
Functions receive arguments the same way scripts do — via $1, $2, $@, etc. These are local to the function (they shadow but don't overwrite the script-level positional params).
function greet_user {
local name="$1"
local role="${2:-user}" # default if not provided
echo "Hello, $name! You are a $role."
}
greet_user "Alice" "admin" # Hello, Alice! You are a admin.
greet_user "Bob" # Hello, Bob! You are a user.Returning Values — The Echo Pattern
return in Bash can only return an integer (0–255) as an exit code, not a string. To "return" a string from a function, print it with echo and capture it with $():
function get_greeting {
local name="$1"
echo "Hello, $name!" # "return" via stdout
}
# Capture the output
message=$(get_greeting "Alice")
echo "$message" # Hello, Alice!
# You can also use return for status codes
function is_root {
[[ $EUID -eq 0 ]] # return 0 (true) if root, 1 if not
}
if is_root; then
echo "Running as root"
fiA Practical Example — Logging
#!/usr/bin/env bash
LOG_FILE="/tmp/myscript.log"
function log_info {
echo "[INFO] $(date '+%F %T') — $*" | tee -a "$LOG_FILE"
}
function log_error {
echo "[ERROR] $(date '+%F %T') — $*" | tee -a "$LOG_FILE" >&2
}
function log_warn {
echo "[WARN] $(date '+%F %T') — $*" | tee -a "$LOG_FILE"
}
# Usage
log_info "Script started"
log_warn "Disk usage is high"
log_error "Failed to connect to database"Functions as a Main Structure
#!/usr/bin/env bash
function usage {
echo "Usage: $0 [options]" >&2
exit 1
}
function setup {
log_info "Setting up..."
mkdir -p /tmp/myapp
}
function cleanup {
log_info "Cleaning up..."
rm -rf /tmp/myapp
}
function main {
[[ $# -eq 0 ]] && usage
setup
# ... do work ...
cleanup
echo "Done"
}
# Call main with all script arguments
main "$@"How do you return a string value from a Bash function?
Write a function to_upper that:
- Takes a string as argument
- Returns it in uppercase (use parameter expansion
${var^^}) - Call it with "hello world" and store the result in a variable, then print it