Introduction
When writing scripts, you will often find yourself needing to repeat the same block of code multiple times. Instead of rewriting or copy-pasting that code, you can use Functions.
A function is a named block of code that performs a specific task. You define it once, and then you can call it whenever you need it. This makes your scripts:
- Modular: Easier to read and manage.
- Reusable: Write once, use many times.
- Maintainable: If you need to change logic, you only update it in one place.
Functions matter because larger scripts become hard to reason about if everything lives in one long top-to-bottom block. Breaking a script into functions is one of the first steps from "quick shell hack" toward "maintainable automation."
In this lab, you will learn the fundamentals of rewriting a script using functions. You will:
- Create a basic script.
- Define a function named
greet_user. - Call the function to execute it.
- Enhance the function to accept parameters (arguments).
Create the Script File
Let's start by setting up our workspace. We will create a file named functions.sh to contain our code.
At this stage, the script file is still just a container. The important shift in this lab is not the file itself, but the idea that a script can be organized into named pieces instead of one long top-to-bottom sequence.
First, navigate to the project directory and create the file:
cd ~/project
touch functions.sh
Next, open the file in the text editor to add the standard Shebang header:
nano functions.sh
Add the following line at the top of the file:
#!/bin/bash
Save the file (Ctrl+O, Enter) and exit (Ctrl+X).
Finally, make the script executable so we can run it later:
chmod +x functions.sh
Now you are ready to start writing code.
Define a Function
Now we will define a function called greet_user.
In Bash, you define a function by writing its name followed by parentheses (), and then enclosing the code block in curly braces {}.
A function gives a block of commands a reusable name. This is how shell scripts become more readable: instead of seeing raw commands everywhere, you start to see actions with meaningful names such as backup_files, check_disk, or greet_user.
The syntax looks like this:
function_name() {
## Commands to execute
}
Open your script again:
nano functions.sh
Add the following function definition below the Shebang line:
#!/bin/bash
greet_user() {
echo "Hello"
}
Important: At this point, we have only defined the function. We haven't told the script to actually run it yet. If you were to run the script now, nothing would happen. This is a common point of confusion for beginners—defining a function does not automatically execute it.
That distinction matters because a shell script is read and executed in order. A function definition teaches Bash what the function means, but the body is not executed until the function name is called later.
Save and Exit for now.
Call the Function
To execute the code inside a function, you must "call" it. In Bash, you call a function simply by writing its name on a new line. You do not need to use parentheses when calling it.
This often looks unusual to beginners because many programming languages use parentheses in function calls. In Bash, greet_user by itself is treated like a command. If a function with that name exists, Bash runs the function body.
Open the script:
nano functions.sh
Add the function call at the bottom of the file:
#!/bin/bash
greet_user() {
echo "Hello"
}
## The Main Logic starts here
greet_user
Save and Exit.
Now, run the script:
./functions.sh
When the script runs, the shell sees the command greet_user, finds the function definition, executes echo "Hello", and then continues.
In that sense, a function behaves much like a custom command that exists only inside the current script or shell session. This is why functions are so useful for building higher-level actions from smaller shell commands.
You should see the output:
Hello
Pass Arguments to the Function
A function that always does the exact same thing (like printing "Hello") is limited. To make it more useful, we can pass data into it. This data is called an argument.
Inside a function, you can access arguments using special variables like $1, $2, etc., just like you do with script arguments.
$1refers to the first argument passed to the function.$2refers to the second argument, and so on.
These are separate from the script's own positional parameters at the moment the function runs. In other words, functions can have their own little input interface, which makes them easier to reuse with different values.
Let's modify our function to greet a specific name.
Step 1: Update the Function Definition
Open the file:
nano functions.sh
Change the greet_user function to use $1 instead of a hardcoded string:
greet_user() {
echo "Hello $1"
}
Step 2: Update the Function Call
Now that the function expects an argument, we need to provide it when calling the function.
Change the call from greet_user to greet_user "LabEx".
Your file should now look like this:
#!/bin/bash
greet_user() {
echo "Hello $1"
}
greet_user "LabEx"
Save and Exit.
Step 3: Test the Script
Run the script again:
./functions.sh
The output should now be:
Hello LabEx
You have essentially created a custom command that takes input and processes it. You could call greet_user "Alice" or greet_user "Bob" later in the script, and it would adapt accordingly.
Summary
In this lab, you learned the basics of Bash functions:
- Defining: Creating a named block of code using
name() { ... }. - Calling: Executing the function by simply typing its name.
- Arguments: Passing data to the function and accessing it via
$1,$2, etc.
Functions are the building blocks of complex scripts. They allow you to organize your logic, reduce repetition, and make your code easier to read and maintain.



