Shell Script Tutorial for Beginners - Bash Variables, If, and Loops

Shell Script Tutorial for Beginners - Bash Variables, If, and Loops

Shell scripting is a powerful tool for automating tasks in Linux systems. In this basics edition, you'll learn Bash script syntax from variables and conditionals to loops, with practical examples throughout.

Your First Shell Script

Basic Structure

#!/bin/bash
# This is a comment

echo "Hello, Shell Script!"
echo "Current date/time: $(date)"
echo "Username: $USER"

Creating and Running Scripts

Step 1: Create File

$ nano hello.sh

Enter the above code and save.

Step 2: Add Execute Permission

$ chmod +x hello.sh

Step 3: Run Script

$ ./hello.sh
Hello, Shell Script!
Current date/time: Mon Jan 11 14:30:00 JST 2025
Username: user

About Shebang

#!/bin/bash is called a shebang and specifies the interpreter to execute this file.

  • #!/bin/bash — Use Bash
  • #!/bin/sh — Use POSIX shell
  • #!/usr/bin/env bash — Auto-detect from environment

Variables and Input

Variable Basics

#!/bin/bash

# Define variables (no spaces around =)
name="Linux User"
age=25
today=$(date +%Y-%m-%d)

# Use variables
echo "Name: $name"
echo "Age: ${age} years old"
echo "Today's date: $today"

Calculation Example

#!/bin/bash

num1=10
num2=3

sum=$((num1 + num2))
diff=$((num1 - num2))
product=$((num1 * num2))
quotient=$((num1 / num2))

echo "Addition: $num1 + $num2 = $sum"
echo "Subtraction: $num1 - $num2 = $diff"
echo "Multiplication: $num1 × $num2 = $product"
echo "Division: $num1 ÷ $num2 = $quotient"

Special Variables

Variable Description Example
$0 Script name ./script.sh
$1, $2, ... Command line arguments 1st arg, 2nd arg
$# Number of arguments 3 for 3 arguments
$@ All arguments "arg1" "arg2" "arg3"
$? Exit status of last command 0 for success, non-0 for failure
$$ Current process ID 12345
$USER Current username user
$HOME Home directory /home/user
$PWD Current directory /home/user/scripts

User Input

Basic Input

#!/bin/bash

echo "Please enter your name:"
read name
echo "Hello, ${name}!"

Input with Prompt

#!/bin/bash

read -p "Enter your age: " age
read -s -p "Enter password: " password
echo
echo "Age: $age"
echo "Password entered silently"

Multiple Values at Once

#!/bin/bash

echo "Enter name and age (space-separated):"
read name age
echo "Name: $name, Age: $age"

Conditionals

if Statement

Basic if Statement

#!/bin/bash

read -p "Enter a number: " num

if [ "$num" -gt 0 ]; then
    echo "$num is positive"
elif [ "$num" -lt 0 ]; then
    echo "$num is negative"
else
    echo "$num is zero"
fi

File Existence Check

#!/bin/bash

filename="test.txt"

if [ -f "$filename" ]; then
    echo "$filename exists"
    echo "File size: $(wc -c < "$filename") bytes"
else
    echo "$filename does not exist"
    echo "Creating file..."
    touch "$filename"
fi

Conditional Operators

Numeric Comparison

Operator Meaning Example
-eq Equal [ $a -eq $b ]
-ne Not equal [ $a -ne $b ]
-gt Greater than [ $a -gt $b ]
-ge Greater or equal [ $a -ge $b ]
-lt Less than [ $a -lt $b ]
-le Less or equal [ $a -le $b ]

String Comparison

Operator Meaning Example
= Equal [ "$a" = "$b" ]
!= Not equal [ "$a" != "$b" ]
-z Empty string [ -z "$str" ]
-n Not empty [ -n "$str" ]

File Tests

Operator Meaning Example
-f Regular file [ -f file.txt ]
-d Directory [ -d /home ]
-e Exists [ -e path ]
-r Readable [ -r file ]
-w Writable [ -w file ]
-x Executable [ -x script ]

case Statement

#!/bin/bash

echo "Select an option:"
echo "1) List files"
echo "2) Show current time"
echo "3) Show system info"
echo "4) Exit"

read -p "Choice (1-4): " choice

case $choice in
    1)
        echo "=== File List ==="
        ls -la
        ;;
    2)
        echo "=== Current Time ==="
        date
        ;;
    3)
        echo "=== System Info ==="
        uname -a
        ;;
    4)
        echo "Exiting."
        exit 0
        ;;
    *)
        echo "Invalid choice."
        ;;
esac

Loops

for Loop

Basic for Loop

#!/bin/bash

# Numeric range
for i in {1..5}
do
    echo "Count: $i"
done

echo "---"

# File processing
for file in *.txt
do
    echo "Processing: $file"
    wc -l "$file"
done

Loop with Arrays

#!/bin/bash

fruits=("apple" "banana" "orange" "grape")

echo "Fruit list:"
for fruit in "${fruits[@]}"
do
    echo "- $fruit"
done

C-style for Loop

#!/bin/bash

echo "Multiplication table (partial):"
for ((i=1; i<=5; i++))
do
    for ((j=1; j<=5; j++))
    do
        result=$((i * j))
        printf "%2d " $result
    done
    echo
done

while Loop

Basic while Loop

#!/bin/bash

count=1
while [ $count -le 5 ]
do
    echo "Loop iteration $count"
    count=$((count + 1))
done

Reading Files

#!/bin/bash

filename="data.txt"

if [ -f "$filename" ]; then
    while IFS= read -r line
    do
        echo "Read: $line"
    done < "$filename"
else
    echo "File $filename not found"
fi

until Loop

#!/bin/bash

count=1
until [ $count -gt 5 ]
do
    echo "Count: $count"
    count=$((count + 1))
done

Loop Control

  • break — Exit loop
  • continue — Skip to next iteration
#!/bin/bash

for i in {1..10}
do
    if [ $i -eq 3 ]; then
        echo "Skipping 3"
        continue
    fi

    if [ $i -eq 8 ]; then
        echo "Stopping at 8"
        break
    fi

    echo "Number: $i"
done

Common Beginner Mistakes and Pitfalls

Mistake 1: Spaces in Variable Assignment

NG (causes error)

name = "Taro"     # Space before/after =
age= 25          # Space after =
city ="Tokyo"     # Space before =

Results in "command not found" error.

OK (correct usage)

name="Taro"      # No spaces around =
age=25
city="Tokyo"

Variable assignment must have no spaces around =.

Mistake 2: Missing Braces in Variable Reference

NG (unexpected results)

filename="test"
echo "$filenameback.txt"    # Empty
echo "$filename_backup"     # Empty

OK (correct usage)

filename="test"
echo "${filename}back.txt"   # testback.txt
echo "${filename}_backup"    # test_backup

Use {} to clearly define variable name scope.

Mistake 3: Missing Spaces in if Statement Conditions

NG (syntax error)

if [$num -gt 5]; then       # No space after [
if [ $num -gt 5]; then      # No space before ]

OK (correct usage)

if [ $num -gt 5 ]; then     # Spaces inside [ ] required
if [[ $num -gt 5 ]]; then   # Same for [[ ]]
if (( num > 5 )); then      # Arithmetic expression

Mistake 4: Missing Quotes in String Comparison

NG (dangerous examples)

if [ $name = John Doe ]; then    # Issues with spaces
if [ $empty_var = "" ]; then     # Error when empty

OK (safe usage)

if [ "$name" = "John Doe" ]; then    # Quote both sides
if [ "$empty_var" = "" ]; then       # No error when empty
if [ -z "$var" ]; then               # Dedicated empty check option

Mistake 5: Old Command Substitution Syntax

NG (not recommended)

date=`date`                 # Backticks
result=`cat `which ls``     # Nesting causes error

OK (modern syntax)

date=$(date)                # Use $()
result=$(cat $(which ls))   # Easy to nest

Mistake 6: Arithmetic Operation Errors

NG (not calculated)

result = $num1 + $num2      # Interpreted as a "result" command (command not found)
sum="$a + $b"               # Not calculated

OK (correct calculation methods)

result=$((num1 + num2))     # Arithmetic expansion
let "result = num1 + num2"  # Use let command

Basic Rules to Prevent Mistakes

Writing Basics

  • Variable assignment: no spaces around =
  • Variable usage: always quote "$var"
  • Complex variables: use braces "${var}"

Conditional Basics

  • Using [ ]: always include internal spaces
  • String comparison: quote both sides
  • Numeric comparison: use -eq, -gt, -lt, etc.

Debugging and Troubleshooting

#!/bin/bash

# Enable debug mode
set -x              # Display command execution
set -e              # Stop on error
set -u              # Error on undefined variables

# Check variable contents
echo "DEBUG: var = [$var]"

# Check file existence
if [ ! -f "$filename" ]; then
    echo "ERROR: File $filename not found" >&2
    exit 1
fi

Common Error Messages and Solutions

  • "command not found": Unnecessary spaces in variable assignment, missing execute permission → chmod +x script.sh
  • "syntax error": Missing spaces inside [ ] in if statement, quote mismatch, missing keywords (then, fi, done)
  • "Permission denied": No execute permission → chmod +x script.sh

Next Reading