Linux Shell Scripting Basics for Automation Tasks

Linux 9 min readPublished 11 October 2026

Quick answer

Learn Linux shell scripting basics through practical Bash examples. Build scripts for backups, service checks, logging and scheduled automation.

Linux shell scripting turns a sequence of terminal commands into a reusable automation tool. A script can collect system information, check services, process files, create backups or run deployment steps consistently.

This guide teaches the core syntax through practical Bash examples. You should be comfortable navigating directories and running basic Linux commands before starting.

What Is a Linux Shell Script?

A Linux shell script is a text file containing commands that a shell reads and executes in order. Bash is commonly used for scripting on Linux, although other shells such as sh, zsh and ksh are also available.

Think of the execution flow as a diagram in words:

Script file → Bash interpreter → command expansion → command execution → output and exit status

The shell reads a line, expands variables and command substitutions, runs the command, and records whether it succeeded. This makes it possible to use decisions, loops and error handling around normal Linux commands.

Shell script versus interactive command

Interactive terminalShell script
Commands are entered manuallyCommands are stored in a file
Suitable for one-time workSuitable for repeatable work
Results depend on manual stepsLogic can validate inputs and failures
Difficult to schedule as a workflowCan run through cron or another scheduler

Shell scripts are useful in DevOps because they connect operating system commands, cloud CLIs and deployment tools. Learners building these operational skills can explore the practical modules in the AWS DevOps course.

How Do You Create and Run a Bash Script?

Create a text file, add a Bash shebang, grant execute permission and run the file. The shebang tells Linux which interpreter should process the script.

Create a file named hello.sh:

#!/usr/bin/env bash

echo "Hello from Bash"
date
whoami

The first line is the shebang:

#!/usr/bin/env bash

Using /usr/bin/env bash finds Bash through the current PATH. A fixed #!/bin/bash shebang is also common when Bash is known to exist at that location.

Make the file executable and run it:

chmod +x hello.sh
./hello.sh

Example output:

Hello from Bash
Sun Oct 11 10:30:14 IST 2026
student

Alternatively, run it by passing the file directly to Bash:

bash hello.sh

This method does not require execute permission, but Bash must have read permission on the file. For a deeper explanation of mode bits and ownership, see Linux file permissions and ownership.

How Do Variables and Command Substitution Work?

Variables store text or numbers for later use, while command substitution captures the output of another command. Do not place spaces around the = sign in a Bash variable assignment.

server_name="web01"
backup_dir="/var/backups/app"
current_date=$(date +%F)

echo "Server: $server_name"
echo "Backup directory: $backup_dir"
echo "Date: $current_date"

Double quotes allow variables to expand. Single quotes preserve the text literally:

name="Anita"
echo "User: $name"
echo 'User: $name'

Output:

User: Anita
User: $name

Quote variable expansions unless you specifically need word splitting or wildcard expansion:

cp "$source_file" "$destination_dir/"

Without quotes, a path such as /home/student/project files would be treated as multiple arguments.

Environment variables

Environment variables are inherited by child processes. Common examples include HOME, USER, PATH and SHELL.

echo "$HOME"
echo "$PATH"
export APP_ENV="testing"

Use export when programs launched by the script need access to the variable.

How Does a Script Accept Input and Arguments?

A script can accept positional arguments from its command line or request interactive input with read. Positional arguments are generally better for unattended automation because they do not require a person at the terminal.

Create greet.sh:

#!/usr/bin/env bash

name=${1:-"Guest"}
environment=${2:-"development"}

echo "Hello, $name"
echo "Environment: $environment"

Run it with two arguments:

./greet.sh Ravi production

Important argument variables include:

VariableMeaning
$0Script name
$1 to $9Positional arguments
$#Number of arguments
"$@"All arguments, preserving boundaries
$?Exit status of the previous command

For interactive input:

read -r -p "Enter the service name: " service_name
echo "Checking $service_name"

The -r option prevents backslashes from being interpreted as escape characters. Avoid interactive prompts in scripts intended for cron, CI/CD or remote automation.

How Do Conditions and Exit Codes Control a Script?

Conditions let a script choose an action based on file state, values or command results. Linux commands normally return exit status 0 for success and a non-zero status for failure.

The flow can be pictured as:

Test condition → true branch runs → continue Test condition → false branch runs → alternative action or exit

This example validates a directory argument:

#!/usr/bin/env bash

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

target_dir=$1

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

Common test operators are:

TestMeaning
-f FILEFile exists and is a regular file
-d DIRDirectory exists
-r FILECurrent process can read the file
-w FILECurrent process can write the file
-z STRINGString is empty
STRING1 == STRING2Strings are equal inside [[ ]]
NUMBER1 -gt NUMBER2First number is greater

Use && to run a command after success and || to react to failure:

mkdir -p "$HOME/reports" && echo "Report directory is ready"

systemctl is-active --quiet sshd || echo "sshd is not active"

The SSH service may be named ssh instead of sshd on some distributions.

How Do Loops Automate Repeated Tasks?

Loops repeat commands over a list or while a condition remains true. A for loop is suitable for known items, while a while loop is useful when reading files or testing changing conditions.

For loop example

#!/usr/bin/env bash

for host in web01 web02 db01; do
    echo "Processing $host"
done

To loop over script arguments safely:

for item in "$@"; do
    printf 'Argument: %s\n' "$item"
done

Reading a file line by line

Suppose servers.txt contains one hostname per line:

web01
web02
db01

Read it with:

while IFS= read -r server; do
    [[ -z "$server" ]] && continue
    echo "Checking $server"
done < servers.txt

IFS= preserves leading and trailing whitespace, while read -r prevents backslash processing. The input redirection keeps the loop in the current shell, which matters if variables changed inside the loop are needed later.

Why Should Bash Scripts Use Functions?

Functions group related commands into reusable units, reducing duplication and making scripts easier to test. A function can receive positional arguments and return a command-style exit status.

#!/usr/bin/env bash

log_message() {
    local level=$1
    local message=$2
    printf '%s [%s] %s\n' "$(date '+%F %T')" "$level" "$message"
}

check_service() {
    local service=$1

    if systemctl is-active --quiet "$service"; then
        log_message "INFO" "$service is active"
        return 0
    else
        log_message "ERROR" "$service is inactive"
        return 1
    fi
}

check_service "sshd"

local limits a variable to its function. return is used for numeric status codes; use echo or printf if a function must produce text that will be captured.

How Can You Build a Practical Backup Script?

A reliable backup script should validate its source, create the destination, generate a unique archive name and report failures. It should also quote paths and return a non-zero status when the backup cannot be created.

The following script archives a directory and removes archives older than seven days:

#!/usr/bin/env bash

set -u

source_dir=${1:-"/etc"}
backup_dir=${2:-"$HOME/backups"}
timestamp=$(date '+%Y%m%d_%H%M%S')
archive="$backup_dir/backup_$timestamp.tar.gz"

log() {
    printf '%s %s\n' "$(date '+%F %T')" "$1"
}

if [[ ! -d "$source_dir" ]]; then
    log "ERROR: Source directory does not exist: $source_dir" >&2
    exit 1
fi

if ! mkdir -p "$backup_dir"; then
    log "ERROR: Cannot create backup directory: $backup_dir" >&2
    exit 1
fi

log "Creating backup of $source_dir"

if tar -czf "$archive" -C "$(dirname "$source_dir")" "$(basename "$source_dir")"; then
    log "Backup created: $archive"
else
    log "ERROR: Backup failed" >&2
    rm -f "$archive"
    exit 1
fi

find "$backup_dir" -type f -name 'backup_*.tar.gz' -mtime +7 -delete
log "Old backup cleanup completed"

Run it with defaults:

./backup.sh

Or provide source and destination paths:

./backup.sh /opt/application /mnt/backup/application

The -C option changes directory before archiving, preventing the archive from storing a long absolute-style path. set -u reports an error when an unset variable is expanded. Stricter modes such as set -e and set -o pipefail are useful, but they should be introduced carefully because expected non-zero results can terminate a script unexpectedly.

How Do You Schedule a Script with Cron?

Cron runs commands on a time-based schedule without interactive input. Use absolute paths, redirect output to a log and confirm that the cron environment contains every required variable.

Edit the current user's crontab:

crontab -e

Run the backup every day at 2:30 AM:

30 2 * * * /home/student/scripts/backup.sh /etc /home/student/backups >> /home/student/logs/backup.log 2>&1

The five scheduling fields represent:

minute hour day-of-month month day-of-week command

Cron usually has a smaller PATH than an interactive shell. Use absolute command paths when needed, create the log directory beforehand, and ensure the cron user has permission to access every source and destination.

How Do You Troubleshoot Shell Scripts?

Start by checking syntax, permissions, interpreter paths, variables and command exit codes. Bash tracing then shows expanded commands in execution order, which helps locate the failing line.

1. Check syntax without running the script

bash -n backup.sh

No output normally means that Bash found no syntax error.

2. Enable execution tracing

bash -x backup.sh

Or trace only part of a script:

set -x
command_to_debug
set +x

Do not use tracing around passwords, tokens or other secrets because expanded values may appear in logs.

3. Inspect the exit code

./backup.sh
echo "$?"

A non-zero value indicates failure. Capture it immediately because the next command replaces $?.

4. Check common execution errors

ErrorLikely causeFix
Permission deniedExecute bit missing or directory inaccessibleUse chmod +x script.sh and check parent permissions
bad interpreterInvalid shebang or Windows line endingsCorrect the shebang; use sed -i 's/\r$//' script.sh
command not foundIncorrect command or limited PATHCheck with command -v name; use an absolute path if required
unbound variableUnset variable with set -uInitialise the variable or use ${value:-default}
Works manually, fails in cronDifferent environment, path or permissionsUse absolute paths and redirect logs

ShellCheck can identify quoting errors, unsafe expansions and portability problems when it is installed:

shellcheck backup.sh

For problems involving storage, processes, services or system logs, follow a structured Linux troubleshooting workflow instead of changing the script at random.

What Are the Main Shell Scripting Practices to Remember?

Good scripts validate input, quote variable expansions, check failures and produce useful logs. Begin with small scripts, test each command independently, and only then schedule or deploy the automation.

  • Use a clear shebang.
  • Prefer printf for predictable formatted output.
  • Quote paths and variables as "$variable".
  • Use "$@" when forwarding arguments.
  • Send error messages to standard error with >&2.
  • Return meaningful non-zero exit codes on failure.
  • Avoid placing passwords or access keys directly in scripts.
  • Test with bash -n, bash -x and ShellCheck.
  • Use version control to review script changes.

Summary

Linux shell scripting basics include interpreters, variables, arguments, conditions, loops, functions, exit codes and scheduling. Together, these features turn normal Linux commands into repeatable automation for backups, monitoring, file processing and operational tasks.

To practise shell automation alongside Git, CI/CD, containers and cloud operations, enquire about curriculum and batch details for the AWS DevOps course.

Reviewed by Network Rhinos Linux and DevOps trainers.

Related reading: SSH Hardening on Linux: Keys, Settings and Mistakes

Frequently asked questions

What is Linux shell scripting used for?

Linux shell scripting is used to automate repeatable command-line tasks such as backups, log processing, service checks and file management. It is also used to connect tools within deployment and system administration workflows.

Is Bash the same as a Linux shell?

Bash is one type of Linux shell and a widely used scripting interpreter. Linux can also use shells such as `sh`, `zsh` and `ksh`, which differ in features and syntax.

How do I make a shell script executable?

Run `chmod +x script.sh` to add execute permission, then start it with `./script.sh`. The script must also have a valid shebang, and the user needs access to the script and its parent directories.

What does an exit status of zero mean in Bash?

An exit status of `0` normally means that a command completed successfully. A non-zero status indicates an error or another result that the command considers unsuccessful.

Should variables always be quoted in Bash scripts?

Variable expansions should normally be enclosed in double quotes, such as `"$file"`. Quoting prevents paths containing spaces or wildcard characters from being split or expanded unexpectedly.

How can I debug a Bash script?

Use `bash -n script.sh` to check syntax and `bash -x script.sh` to trace commands during execution. Also inspect exit codes, permissions, the shebang, environment variables and logs, but avoid tracing commands that expose secrets.

Related articles

Train with Network Rhinos

Hands-on CCNA, CCNP, AWS, Azure, DevOps and cybersecurity training in Chennai & Bangalore, with placement support. Talk to our team or attend a free demo class.