Bash functions explained banner
Bash focus guide

Bash Functions Explained

Bash functions let you write a block of code once, give it a name, and reuse it whenever your script needs it. They help turn one long script into cleaner, safer, easier-to-maintain automation.

On this page
Basics

What is a Bash function?

A Bash function is a reusable block of shell commands. Instead of copying the same lines again and again, you define the function once and call it by name.

Functions are useful when your script has repeated tasks such as checking a service, printing a status message, validating arguments, logging output, checking disk usage or testing a website.

Think of a function as a named mini-script inside your script. It keeps related commands together and makes the main script easier to read.
Syntax

Basic Bash function syntax

The most common syntax is:

function_name() {
  command
  command
}

Example:

say_hello() {
  echo "Hello from Bash"
}

You may also see this style:

function say_hello {
  echo "Hello from Bash"
}

The first style, name() { ... }, is widely used and portable across normal Bash scripts.

Calling

Calling a Bash function

Defining a function does not run it. You call it by writing the function name later in the script.

#!/usr/bin/env bash

say_hello() {
  echo "Hello from Bash"
}

say_hello
$ bash hello-function.sh
Hello from Bash

The function must normally be defined before you call it. Bash reads the script from top to bottom, so calling a function before it exists can fail.

Arguments

Passing arguments to Bash functions

Function arguments work much like script arguments. Inside a function, $1 is the first argument passed to the function, $2 is the second, and $@ means all function arguments.

#!/usr/bin/env bash

greet_user() {
  echo "Hello, $1"
}

greet_user "Robbie"
greet_user "Linux Admin"
$ bash greet.sh
Hello, Robbie
Hello, Linux Admin

Use quotes when passing values that may contain spaces. Without quotes, "Linux Admin" becomes two separate words. Bash is helpful like that, in the same way a cat is helpful when walking across your keyboard.

Using multiple arguments

#!/usr/bin/env bash

show_user() {
  echo "Username: $1"
  echo "Role: $2"
}

show_user "alice" "developer"
$ bash user-role.sh
Username: alice
Role: developer

For script-level arguments, see Bash script arguments explained.

Reusable help

Create a usage function

A usage function is one of the most useful functions in beginner scripts. It prints a short help message when the user runs the script incorrectly.

#!/usr/bin/env bash

usage() {
  echo "Usage: $0 <domain>"
  echo "Example: $0 example.com"
}

if [ "$#" -ne 1 ]; then
  usage
  exit 1
fi

domain="$1"
echo "Checking domain: $domain"
$ bash check-domain.sh
Usage: check-domain.sh <domain>
Example: check-domain.sh example.com
$ bash check-domain.sh commandlinequiz.com
Checking domain: commandlinequiz.com

This keeps the help text in one place. If you change the script later, you only update the usage function.

Scope

Use local variables inside functions

By default, Bash variables are global. That means a variable created inside a function can affect the rest of the script. Use local for variables that should only exist inside the function.

#!/usr/bin/env bash

server="production"

show_server() {
  local server="staging"
  echo "Inside function: $server"
}

show_server
echo "Outside function: $server"
$ bash local-variable.sh
Inside function: staging
Outside function: production

Using local helps prevent accidental variable clashes as your scripts grow.

Exit status

Return success or failure from a function

In Bash, return is normally used for exit codes, not for returning text. A return code of 0 means success. Non-zero means failure.

#!/usr/bin/env bash

check_file() {
  local file="$1"

  if [ -f "$file" ]; then
    return 0
  else
    return 1
  fi
}

if check_file "/etc/passwd"; then
  echo "File exists"
else
  echo "File is missing"
fi
$ bash check-file.sh
File exists

This pattern is clean because the function can be used directly inside an if statement. For more condition examples, read Bash operators explained.

Checking the return code manually

check_file "/tmp/example.txt"
result=$?

echo "Function returned: $result"
Output

Return text using echo and command substitution

If you want a function to give back text, print it with echo and capture it with command substitution.

#!/usr/bin/env bash

get_date_stamp() {
  date "+%Y-%m-%d"
}

stamp=$(get_date_stamp)
echo "Backup date: $stamp"
$ bash date-function.sh
Backup date: 2026-05-05
Use return for success or failure. Use echo when you want to capture text output.
Real examples

Practical Bash function examples

1. Disk usage checker function

This function checks a mount point and warns if disk usage is above a threshold.

#!/usr/bin/env bash

check_disk_usage() {
  local mount_point="$1"
  local warning_level="$2"
  local usage

  usage=$(df -P "$mount_point" | awk 'NR==2 {gsub("%", "", $5); print $5}')

  if [ "$usage" -ge "$warning_level" ]; then
    echo "[WARN] $mount_point is $usage% full"
    return 1
  else
    echo "[OK] $mount_point is $usage% full"
    return 0
  fi
}

check_disk_usage "/" 80
check_disk_usage "/home" 85
$ bash check-disk.sh
[OK] / is 42% full
[WARN] /home is 91% full

This fits naturally with the Linux high disk usage troubleshooting guide.

2. Service status checker function

This function checks whether a systemd service is running.

#!/usr/bin/env bash

check_service() {
  local service="$1"

  if systemctl is-active --quiet "$service"; then
    echo "[OK] $service is running"
    return 0
  else
    echo "[WARN] $service is not running"
    return 1
  fi
}

check_service "sshd"
check_service "crond"
check_service "httpd"
$ bash check-services.sh
[OK] sshd is running
[OK] crond is running
[WARN] httpd is not running

If you want to understand the service commands used here, read the systemd services guide.

3. Website status checker function

This function checks a URL and reports the HTTP status code and response time.

#!/usr/bin/env bash

check_website() {
  local url="$1"
  local result status time_total

  result=$(curl -o /dev/null -s -w "%{http_code} %{time_total}" "$url")
  status=$(echo "$result" | awk '{print $1}')
  time_total=$(echo "$result" | awk '{print $2}')

  if [ "$status" = "200" ]; then
    echo "[OK] $url returned $status in ${time_total}s"
    return 0
  else
    echo "[WARN] $url returned $status in ${time_total}s"
    return 1
  fi
}

check_website "https://example.com"
check_website "https://commandlinequiz.com"
$ bash check-websites.sh
[OK] https://example.com returned 200 in 0.147221s
[OK] https://commandlinequiz.com returned 200 in 0.208456s

For a full monitoring script, see the Bash website uptime monitor guide.

4. Logging function

A simple logging function keeps output consistent across a script.

#!/usr/bin/env bash

log_msg() {
  local level="$1"
  local message="$2"
  local timestamp

  timestamp=$(date "+%Y-%m-%d %H:%M:%S")
  echo "[$timestamp] [$level] $message"
}

log_msg "INFO" "Starting backup"
log_msg "WARN" "Disk usage is high"
log_msg "INFO" "Backup complete"
$ bash log-example.sh
[2026-05-05 11:20:00] [INFO] Starting backup
[2026-05-05 11:20:01] [WARN] Disk usage is high
[2026-05-05 11:20:04] [INFO] Backup complete
Reusable scripts

Put functions in a separate file

As scripts grow, you may want to keep common functions in one file and load them from other scripts.

Create functions.sh:

log_msg() {
  local level="$1"
  local message="$2"
  echo "[$level] $message"
}

Then source it from another script:

#!/usr/bin/env bash

source ./functions.sh

log_msg "INFO" "Loaded shared functions"
$ bash main.sh
[INFO] Loaded shared functions
Only source files you trust. Sourcing a file runs the code inside your current shell environment.
Troubleshooting

Common Bash function mistakes

MistakeProblemBetter option
Calling a function before it is definedBash may not know the function exists yet.Define functions near the top of the script, then call them later.
Using return "text"return expects a numeric exit code.Use echo and command substitution for text output.
Not quoting argumentsValues with spaces can split into multiple words.Use "$1", "$file" and "$@".
Using global variables everywhereFunctions can accidentally overwrite values used later.Use local inside functions.
Functions that do too muchHuge functions become hard to test and reuse.Keep each function focused on one clear task.
Practice

Practice exercises

Create a greeting function

Write a function that accepts a name and prints a personalised greeting.

Create a file checker

Write a function that checks whether a path exists, then returns success or failure.

Create a service checker

Write a function that accepts a service name and checks it with systemctl.

Create a logging function

Write a function that prints timestamps and log levels for your scripts.

Keep learning

What should you learn next?

Once you understand Bash functions, you can combine them with arguments, user input, loops and tests to build cleaner admin scripts. This is where Bash starts becoming a proper toolkit rather than a pile of one-liners wearing a trench coat.

$ practise_next --topic bash

Practise this next

Turn the guide into practice with a related quiz, builder, cheat sheet or learning path.