DevOpsLesson
DevOpsLesson

Free, comprehensive DevOps tutorials and learning roadmaps. Master Docker, Kubernetes, CI/CD, and more.

Stay Updated

Get notified about new tutorials and features.

Tutorials

  • What is DevOps?
  • Docker Tutorial
  • Terraform Tutorial
  • CI/CD Pipeline
  • All Tutorials

Roadmaps

  • DevOps Engineer
  • Cloud Engineer
  • SRE Path
  • All Roadmaps

Company

  • About Us
  • Blog
  • Contact
  • Privacy Policy
  • Terms of Service

© 2026 DevOpsLesson. All rights reserved.

DOCKERKUBERNETESTERRAFORMAWSCI/CDLINUXGITDEVOPS ROADMAPCLOUD ROADMAPSRE ROADMAPGIT CHEATSHEETDOCKER CHEATSHEETK8S CHEATSHEETTF CHEATSHEETLINUX CHEATSHEETDOCKERFILE LINTERYAML VALIDATORCRON PARSERREGEX TESTER

Linux Tutorial

Introduction to Linux
Linux Filesystem
Linux Navigation
Linux File Operations
Linux Text Processing
Linux Permissions
Linux Users and Groups
Linux Process Management
Linux systemd Basics
Linux Networking
Linux Disk and Storage
Linux Bash Scripting
Linux Package Management
Linux Environment Variables
Linux Cron Jobs
Linux SSH Keys
Linux Firewall Basics
Linux Log Management
Linux Performance Monitoring and Troubleshooting

Linux Bash Scripting

PreviousPrev
Next

Learn how to write practical Bash scripts with variables, conditionals, loops, functions, arrays, redirection, traps, and exit codes.

Why Bash Scripting Matters

Bash scripting is where Linux command-line knowledge becomes automation. A Bash script can validate environment state, deploy an application, rotate logs, back up files, or glue together tools that do one job each.

Bash is not the best language for every task, but it is excellent for lightweight automation that lives close to the operating system.

Starting with the Shebang

A script usually begins with a shebang line that tells the system which interpreter to use.

#!/usr/bin/env bash

Save the script, make it executable, and run it:

chmod +x deploy.sh
./deploy.sh

Variables and Positional Parameters

Variables store values.

name="devops"
env="production"
echo "$name"

Bash also provides positional parameters for command-line arguments.

echo "$1"
echo "$2"
echo "$#"
  • $1 is the first argument
  • $2 is the second argument
  • $# is the number of arguments
  • $@ represents all arguments

Example:

./backup.sh /var/log nginx

Inside the script, $1 might be /var/log and $2 might be nginx.

Conditionals with if, elif, and else

Use conditionals to make decisions.

if [ -f /etc/nginx/nginx.conf ]; then
  echo "Nginx config exists"
elif [ -d /etc/nginx ]; then
  echo "Nginx directory exists"
else
  echo "Nginx not installed"
fi

Common test operators:

  • -f file exists
  • -d directory exists
  • -z string is empty
  • -n string is not empty

Loops: for and while

A for loop repeats over a list.

for host in app1 app2 app3; do
  echo "Checking $host"
done

A while loop repeats while a condition is true.

count=1
while [ "$count" -le 3 ]; do
  echo "Attempt $count"
  count=$((count + 1))
done

Loops are common in operations scripts that process files, services, or hosts.

Functions

Functions group logic into reusable units.

log_info() {
  echo "[INFO] $1"
}

check_file() {
  if [ -f "$1" ]; then
    echo "Found: $1"
  else
    echo "Missing: $1"
  fi
}

Then call them:

log_info "Starting check"
check_file /etc/hosts

Functions improve readability and reduce duplication.

Arrays and String Operations

Bash supports arrays.

services=(nginx sshd docker)
echo "${services[0]}"
echo "${services[@]}"

Basic string operations are also useful.

filename="app.log"
echo "${filename%.log}"
echo "${filename/app/service}"

These features help with small automation tasks without calling external tools for everything.

Exit Codes

Every command returns an exit code. 0 usually means success. Non-zero means failure.

mkdir testdir
echo $?

In scripts, you often check exit codes directly or stop early on failure.

cp config.yaml config.yaml.bak || exit 1

You can also end your own script with a chosen exit code:

exit 0
exit 1

Standard Input, Output, and Error

Bash scripts interact with three standard streams:

  • stdin: input stream
  • stdout: normal output
  • stderr: error output

Example:

echo "normal message"
echo "error message" >&2

Redirection lets you control where output goes.

./script.sh > output.log 2> error.log
./script.sh < input.txt

This is important when integrating scripts into CI pipelines or scheduled jobs.

Cleaning Up with trap

trap lets you run cleanup code when a script exits or receives a signal.

cleanup() {
  echo "Cleaning up"
}

trap cleanup EXIT

This is useful for removing lock files, stopping background jobs, or printing final status messages.

Tip: trap is a simple way to make scripts safer and more professional.

Practical Example: Argument Validation Script

#!/usr/bin/env bash

if [ "$#" -lt 1 ]; then
  echo "Usage: $0 <directory>" >&2
  exit 1
fi

target_dir="$1"

if [ ! -d "$target_dir" ]; then
  echo "Directory not found: $target_dir" >&2
  exit 2
fi

echo "Listing files in $target_dir"
ls -lah "$target_dir"

This script demonstrates positional parameters, conditionals, stderr, and exit codes.

Practical Example: Service Health Check Script

#!/usr/bin/env bash

services=(nginx sshd docker)

for service in "${services[@]}"; do
  if systemctl is-active --quiet "$service"; then
    echo "$service is running"
  else
    echo "$service is not running" >&2
  fi
done

This type of script is realistic for server health reporting.

Best Practices for Bash Scripts

  • quote variables like "$1" to avoid word-splitting bugs
  • keep scripts focused and readable
  • use functions for repeated logic
  • return meaningful exit codes
  • send errors to stderr when appropriate
  • test scripts with both expected and unexpected input

Bash becomes much easier when you treat it as structured automation, not just a long list of commands.

Test Your Understanding

Let's see how well you understood the concepts! These exercises will help reinforce what you just learned.

Exercise 1: Counting script arguments

Question: In the tutorial, what does $# represent inside a Bash script?

Exercise

Exercise 1: Counting script arguments

Identify what the special parameter $# contains in Bash.

Exercise 2: Writing to stderr

Scenario: Your script wants to print a usage message when no directory argument is provided.

Question: Why does the example use >&2 for that message?

Exercise

Exercise 2: Writing to stderr

Choose why a Bash script redirects an error message to file descriptor 2.

Exercise 3: Registering exit cleanup

Question: What does trap cleanup EXIT do in the lesson's example?

Exercise

Exercise 3: Registering exit cleanup

Identify what the trap statement accomplishes when the script exits.

PreviousPrev
Next

Continue Learning

Linux systemd Basics

Learn how systemd units, targets, systemctl, and journalctl work, and create a simple service unit file.

18 min·Medium

Linux Networking

Learn essential Linux networking commands for inspecting addresses, testing connectivity, transferring files, and understanding DNS resolution.

20 min·Medium

Linux Disk and Storage

Learn how to inspect disk space, mount filesystems, archive data, compress files, and find large files in Linux.

18 min·Medium

Explore Related Topics

Do

Docker Tutorials

Run and manage containers on Linux

Gi

Git Tutorials

Master Git version control on the command line

Try the Tool

Cron Parser

Parse and validate cron expressions with a visual schedule preview.

Regex Tester

Test and debug regular expressions used in Bash scripts and configs.

On This Page

Why Bash Scripting MattersStarting with the ShebangVariables and Positional ParametersConditionals with `if`, `elif`, and `else`Loops: `for` and `while`FunctionsArrays and String OperationsExit CodesStandard Input, Output, and ErrorCleaning Up with `trap`Practical Example: Argument Validation ScriptPractical Example: Service Health Check ScriptBest Practices for Bash ScriptsTest Your UnderstandingExercise 1: Counting script argumentsExercise 2: Writing to stderrExercise 3: Registering exit cleanup