Kahibaro
Discord Login Register

Introduction to Shell Scripting

Why Shell Scripting Matters

Shell scripting lets you automate commands you already know how to run interactively in your shell. Instead of typing a sequence of commands over and over, you write them once in a file (a script) and run that file as a program.

A shell script is simply:

Shell scripts are especially useful for:

This chapter stays focused on beginner-level scripting with bash.

The Shebang Line

Most shell scripts start with a shebang line on the first line:

bash
#!/bin/bash

Common shebangs you’ll see:

bash
#!/bin/bash      # Bash (most common for beginners)
#!/usr/bin/env bash  # More portable, finds bash via PATH
#!/bin/sh        # POSIX shell (more minimal)

If you omit the shebang and run the script like:

bash
bash myscript.sh

then bash will still interpret it, but when you later run ./myscript.sh directly, the shebang becomes important.

Your First Script

Step 1: Create the file

Use any text editor (nano, vim, etc.) to create a file:

bash
nano hello.sh

Add this content:

bash
#!/bin/bash
echo "Hello, world!"

Save and exit.

Step 2: Make it executable

Scripts are just files until you give execute permission:

bash
chmod +x hello.sh

Now you can run it with:

bash
./hello.sh

If you see Permission denied, you probably missed the chmod step, or you’re not in the directory with the script.

You can always run a script explicitly with the shell even without chmod +x:

bash
bash hello.sh

But making it executable and using the shebang is the usual practice.

Basic Script Structure

A simple bash script often follows this pattern:

bash
#!/bin/bash
# 1. Optional: configuration and variables
BACKUP_DIR="$HOME/backups"
# 2. Optional: simple checks
[ ! -d "$BACKUP_DIR" ] && mkdir -p "$BACKUP_DIR"
# 3. Main commands
echo "Backing up documents..."
cp -r "$HOME/Documents" "$BACKUP_DIR"
echo "Done."

Key points:

Running Scripts Safely

Shell scripts can modify or delete files quickly, so get into safe habits early:

bash
  # Instead of:
  rm "$file"
  # First try:
  echo rm "$file"
bash
  BACKUP_SRC="/home/user/Documents"
bash
  rm "$file"      # safer
  rm $file        # dangerous if $file contains spaces or is empty

Comments and Readability

Good comments make scripts easier to maintain and understand later.

bash
#!/bin/bash
# Simple backup script for my Documents folder
SRC="$HOME/Documents"
DEST="$HOME/backups"
# Create destination directory if it doesn't exist
mkdir -p "$DEST"
# Copy files (-r = recursive, -v = verbose)
cp -rv "$SRC" "$DEST"

Guidelines:

Using Commands in Scripts

Any command you use interactively can go into a script. A script is just a list of commands executed top to bottom.

Example: a basic “system summary” script:

bash
#!/bin/bash
echo "System summary for: $(hostname)"
echo
echo "Date and time:"
date
echo
echo "Current user:"
whoami
echo
echo "Uptime:"
uptime

Note:

Input and Output Basics in Scripts

You can use standard input/output redirection in scripts just like in the terminal.

Example: logging the output of commands to a file:

bash
#!/bin/bash
LOGFILE="$HOME/system-info.log"
{
  echo "===== System Info: $(date) ====="
  uname -a
  echo
  df -h
  echo
  free -h
  echo
} >> "$LOGFILE"

Here:

Redirecting standard output vs standard error:

bash
ls /not/real 1>out.txt 2>err.txt

In scripts you often see:

bash
some_command >>"$LOGFILE" 2>&1

This means: append both normal output and errors to the same file.

Getting User Input (Simple)

You can interactively ask the user for input with read:

bash
#!/bin/bash
echo -n "Enter your name: "
read name
echo "Hello, $name!"

Or a more idiomatic version:

bash
read -rp "Enter your name: " name
echo "Hello, $name!"

A yes/no question:

bash
read -rp "Do you want to continue? [y/N] " answer
echo "You entered: $answer"

(Handling the logic of the answer will be covered in the conditionals chapter.)

Exit Status and `exit`

Every command and script has an exit status, a number where:

You can view the exit status of the last command with $?:

bash
ls /does/not/exist
echo "Exit status: $?"

To set the exit status of your script, use exit:

bash
#!/bin/bash
if ! command -v rsync >/dev/null 2>&1; then
  echo "rsync is not installed."
  exit 1
fi
# ... rest of script ...
exit 0   # optional; if omitted, the script's exit status is that of the last command

Even in simple scripts, using different exit codes can help other tools/scripts detect success or failure.

Good Practices for Beginners

Start building good habits early:

bash
  mv "$old_name" "$new_name"

Example of a small, tidy beginner script:

bash
#!/bin/bash
# Clean the Downloads directory by moving older files to an archive
DOWNLOADS="$HOME/Downloads"
ARCHIVE="$HOME/Downloads/archive"
mkdir -p "$ARCHIVE"
echo "Moving files older than 30 days from $DOWNLOADS to $ARCHIVE..."
find "$DOWNLOADS" -maxdepth 1 -type f -mtime +30 -print -exec mv {} "$ARCHIVE" \;
echo "Done."

(Details of find options would be explained elsewhere; here just notice how a one-liner command becomes reusable through a script.)

Debugging Simple Scripts

When your script doesn’t behave as expected, a few basic techniques help:

bash
  echo "DEBUG: backup directory is '$BACKUP_DIR'"
bash
  bash -x myscript.sh

This prints each command as it’s executed.

bash
  set -x   # turn on tracing
  # ... commands ...
  set +x   # turn off tracing

Start with these before moving to more advanced debugging tools.

Where to Go Next

Once you’re comfortable with creating and running simple scripts:

Each of these topics will be explored in the following sections of this shell scripting module.

Views: 26

Comments

Please login to add a comment.

Don't have an account? Register now!