Bash Functions¶
Lab Highlights:¶
- Lab Highlights:
- 01. Basic Function Structure
- 02. Passing Arguments to Functions
- 03. Returning Values from Functions
- 04. Local vs Global Variables
- 05. Functions with Checks (If/Else)
- 06. Functions with Loops
- 07. Nested Functions
Prefix: Understanding Bash Functions¶
- Functions in Bash are
reusable blocks of codethat perform a specific task. - They help organize scripts, reduce redundancy, and improve readability.
- Functions can accept
argumentsand canreturn values(via output or exit status). - Functions are defined once and can be called multiple times throughout a script.
- Functions can also have
localvariables that do not interfere with global variables. - Functions can include
control structureslike loops and conditionals. - They can be
nested, meaning one function can call another. - Functions enhance modularity, making scripts easier to maintain and debug.
- They are essential for writing efficient and effective Bash scripts.
Defining a Function: You can define a function in two ways:
-
Using the
functionkeyword: -
Using just the name and parentheses (Standard):
Calling a Function:
- To call a function, simply write its name as if it were a command. You do not use parentheses when calling it.
01. Basic Function Structure¶
- This script demonstrates the simplest way to define and call a function.
- It defines a function named
greetthat prints a welcome message. -
The function is then called at the end of the script.
#!/bin/bash # Define the function function greet() { echo "Hello! Welcome to Bash Functions." } # Call the function echo "Calling the function..." greet echo "Function execution finished."What we’re doing:
- Creating a reusable block of code to print a message.
How the script does it:
- The
function greet() { ... }block defines the function. - The code inside the curly braces
{}is not executed until the function is called. greettriggers the execution of the commands inside the function.
02. Passing Arguments to Functions¶
- Functions can accept arguments just like scripts.
- Inside a function,
$1,$2, etc., refer to the arguments passed to the function, not the script. -
$#holds the number of arguments passed to the function.#!/bin/bash # Function to add two numbers add_numbers() { sum=$(( $1 + $2 )) echo "The sum of $1 and $2 is: $sum" } # Call the function with arguments add_numbers 10 20 add_numbers 50 100What we’re doing:
- Passing data into a function to perform a calculation.
How the script does it:
add_numbers 10 20calls the function with10as$1and20as$2.sum=$(( $1 + $2 ))performs arithmetic expansion to calculate the total.- The function is reused with different values (
50and100).
03. Returning Values from Functions¶
- Unlike other programming languages, Bash functions do not return values using a
returnstatement in the traditional sense. returnin Bash is used to set the exit status (0-255) of the function (0 usually means success).-
To “return” a string or result, you typically
echothe value and capture it using command substitution$().#!/bin/bash # Function that 'returns' a value by echoing it get_current_date() { formatted_date=$(date +"%Y-%m-%d") echo "$formatted_date" } # Function that uses 'return' for status check_file_exists() { if [ -f "$1" ]; then return 0 # Success (True) else return 1 # Failure (False) fi } # Capture the output today=$(get_current_date) echo "Today's date is: $today" # Check status if check_file_exists "/etc/passwd"; then echo "File exists!" else echo "File not found." fiWhat we’re doing:
- Retrieving data from a function and checking success/failure status.
How the script does it:
get_current_dateprints the date to stdout.today=$(get_current_date)captures that output into a variable.check_file_existsusesreturn 0orreturn 1. Theifstatement checks this exit code directly.
04. Local vs Global Variables¶
- By default, all variables in Bash are global, even if defined inside a function.
-
Use the
localkeyword to restrict a variable’s scope to the function. This prevents overwriting variables outside the function.#!/bin/bash global_var="I am global" test_scope() { local local_var="I am local" global_var="I have been changed inside function" echo "Inside function: $local_var" echo "Inside function: $global_var" } echo "Before function: $global_var" test_scope echo "After function: $global_var" # echo "After function: $local_var" # This would be empty/undefinedWhat we’re doing:
- Understanding variable scope to write safer scripts.
How the script does it:
local local_varensureslocal_varonly exists withintest_scope.global_varis modified inside the function, and that change persists after the function finishes because it wasn’t declaredlocal.
05. Functions with Checks (If/Else)¶
- This script uses conditional logic inside a function to validate input.
-
It checks if a user is root or a regular user.
#!/bin/bash check_user() { user_id=$(id -u) if [ "$user_id" -eq 0 ]; then echo "You are running as ROOT." else echo "You are running as a regular user (ID: $user_id)." fi } # Call the function check_userWhat we’re doing:
- Encapsulating logic to check the current user’s permissions.
How the script does it:
id -ugets the user ID. Root is always0.- The
ifstatement checks if the ID equals 0 and prints the appropriate message.
06. Functions with Loops¶
- Functions can contain loops to process lists of items.
-
This example defines a function that takes multiple filenames as arguments and checks each one.
#!/bin/bash process_files() { echo "Processing $# files..." # Loop through all arguments passed to the function for file in "$@"; do if [ -e "$file" ]; then echo " [OK] $file exists." else echo " [XX] $file missing." fi done } # Call function with a list of files process_files /etc/hosts /etc/passwd /tmp/missing_file.txtWhat we’re doing:
- Batch processing items passed as arguments to a function.
How the script does it:
"$@"represents all arguments passed to the function.- The
forloop iterates over each file. [ -e "$file" ]checks if the file exists.
07. Nested Functions¶
- You can define functions inside other functions, or call functions from within functions.
-
This helps break down complex tasks into smaller steps.
#!/bin/bash log_msg() { echo "[$(date +%T)] $1" } backup_file() { local file="$1" log_msg "Starting backup for $file" if [ -f "$file" ]; then cp "$file" "${file}.bak" log_msg "Backup created: ${file}.bak" else log_msg "Error: File $file not found" fi } # Main script logic backup_file "data.txt"What we’re doing:
- Using a helper function (
log_msg) inside another function (backup_file) to standardize output.
How the script does it:
log_msghandles the formatting of log messages with a timestamp.backup_filecallslog_msginstead of using rawecho, keeping the code clean and consistent.
- Using a helper function (