Defining and Calling Functions
A shell function groups a set of commands under a name so you can reuse them. Define a function with function name() {} or the shorthand name() {}. Once defined, you call it just like any other command.
Syntax
Style 1 — with the function keyword.
function name() {
commands
}
Style 2 — without the function keyword (POSIX-compatible).
name() {
commands
}
Call the function.
name [arg1] [arg2] ...
Declare a local variable (scoped to the function).
local varname=value
List defined functions.
declare -f # Show definitions of all functions declare -f name # Show definition of a specific function declare -F # List function names only
Function features
| Feature | Description |
|---|---|
| Accessing arguments | Use $1, $2, ... to access arguments passed to the function (separate scope from script-level arguments). |
| local variables | Variables declared with local are not accessible outside the function. |
| return | Exits the function and returns an integer exit status (0–255). |
| Returning a value | To return a string, print it with echo and capture it in the caller using command substitution ($()). |
| Recursion | Functions can call themselves recursively. |
| Definition order | A function must be defined before it is called. |
| unset -f | Removes a defined function. |
Sample Code
Define a function that accepts an argument. Use local to declare a variable scoped to the function.
greet.sh
#!/bin/bash
greet() {
local name="$1"
echo "Hello, ${name}!"
}
greet "Alice"
greet "Bob"
bash greet.sh
Hello, Alice!
Hello, Bob!
You can also define functions directly in the terminal. After pressing Enter following {, a > prompt appears — this signals that input is still expected. Typing } completes the definition.
greet() {
local name="$1"
echo "Hello, ${name}!"
}
greet "Alice"
Hello, Alice!
greet "Bob"
Hello, Bob!
Variables declared without local are in the global scope, so they can be read and modified from outside the function.
counter.sh
counter=0 # Global variable
increment() {
local step="${1:-1}" # Default to 1 if no argument is given
counter=$(( counter + step ))
echo "Inside function — counter: $counter"
}
increment
increment 5
echo "Outside function — counter: $counter"
bash counter.sh
Inside function — counter: 1
Inside function — counter: 6
Outside function — counter: 6
Use return to return an exit status and test it with if.
file_exists.sh
file_exists() {
local path="$1"
if [ -f "$path" ]; then
return 0 # Success (true)
else
return 1 # Failure (false)
fi
}
if file_exists "/etc/hosts"; then
echo "/etc/hosts exists"
fi
bash file_exists.sh
/etc/hosts exists
To return a string, print it with echo and capture it in the caller using $().
timestamp.sh
get_timestamp() {
echo "$(date +%Y%m%d_%H%M%S)"
}
ts=$(get_timestamp)
echo "Timestamp: $ts"
bash timestamp.sh
Timestamp: 20260306_143022
Functions support recursion. The following example computes a factorial.
factorial.sh
factorial() {
local n=$1
if (( n <= 1 )); then
echo 1
else
local prev=$(factorial $(( n - 1 )))
echo $(( n * prev ))
fi
}
echo "5! = $(factorial 5)"
bash factorial.sh
5! = 120
Notes
Variables defined inside a function are global by default. To avoid accidentally modifying global state, always use local for variables inside functions.
Shell functions can only return an exit status directly (an integer from 0–255). To return a string value, print it with echo and capture it in the caller using command substitution ($( )).
For advanced argument handling, see Function arguments and return values.
If you find any errors or copyright issues, please contact us.