Bash Functions
Functions in Bash allow you to group commands for later execution. They help make your scripts more modular, reusable, and easier to maintain.
Defining Functions
There are two syntaxes for defining functions in Bash:
# Syntax 1
function_name() {
commands
}
# Syntax 2
function function_name {
commands
}
Simple Function Example
#!/bin/bash
# Define a function
greet() {
echo "Hello, $1!"
}
# Call the function
greet "World"
greet "Bash Programmer"
Returning Values
Bash functions don't return values like in other languages. Instead, they return an exit status (0 for success, non-zero for failure). You can use return
to set this status.
#!/bin/bash
is_even() {
local num=$1
if (( num % 2 == 0 )); then
return 0 # success (true)
else
return 1 # failure (false)
fi
}
# Test the function
is_even 4 && echo "Even number" || echo "Odd number"
is_even 7 && echo "Even number" || echo "Odd number"
Returning Data
To return data from a function, you can use command substitution to capture its output:
#!/bin/bash
add() {
local sum=$(( $1 + $2 ))
echo $sum # Output the result
}
result=$(add 5 3)
echo "The sum is: $result"
Local Variables
By default, variables in Bash are global. Use the local
keyword to create variables with function scope:
#!/bin/bash
demo_scope() {
local local_var="I'm local"
global_var="I'm global"
echo "Inside function: $local_var, $global_var"
}
demo_scope
echo "Outside function: $local_var, $global_var" # local_var is undefined here
Passing Arguments
Functions receive arguments similarly to scripts, using positional parameters:
#!/bin/bash
show_args() {
echo "First arg: $1"
echo "Second arg: $2"
echo "All args: $@"
echo "Number of args: $#"
}
show_args "apple" "banana" "cherry"
Recursive Functions
Bash supports recursive function calls, though there's usually a limit to the recursion depth:
#!/bin/bash
factorial() {
if (( $1 <= 1 )); then
echo 1
else
local prev=$(( $1 - 1 ))
local result=$(factorial $prev)
echo $(( $1 * result ))
fi
}
echo "Factorial of 5 is: $(factorial 5)"
Best Practices
- Use descriptive function names
- Keep functions small and focused
- Use
local
for variables that shouldn't be global - Document your functions with comments
- Return proper exit statuses (0 for success, non-zero for errors)
Advanced Example
Here's a more complex example demonstrating several function features:
#!/bin/bash
# Function to check if a file exists and is readable
file_exists() {
if [[ ! -f "$1" ]]; then
echo "Error: File '$1' does not exist" >&2
return 1
fi
if [[ ! -r "$1" ]]; then
echo "Error: File '$1' is not readable" >&2
return 1
fi
return 0
}
# Function to count lines in a file
count_lines() {
file_exists "$1" || return 1
local lines=$(wc -l < "$1")
echo "$lines"
}
# Main function
main() {
local filename="$1"
local lines
lines=$(count_lines "$filename") || exit 1
echo "File '$filename' has $lines lines"
if (( lines > 100 )); then
echo "That's a large file!"
fi
}
# Call main with the first argument
main "$1"
Next: Input/Output Redirection