Back to Blog
Lesson 37 of the Linux: Linux Command Line for Developers course
LinuxAugust 25, 20263 min read

Shell Scripting Logic: Mastering Bash for Linux Automation

Master shell scripting logic in Bash. Learn to use if-statements, loops, and arguments to automate your Linux server tasks with real-world examples.

bashshell scriptinglinuxprogrammingautomation
Vibrant and engaging code displayed on a computer screen, showcasing programming concepts.

Previously in this course, we covered automating service scripts with cron, which taught you how to trigger execution at specific intervals. In this lesson, we move from simple command execution to actual shell scripting, adding the logic required to make your scripts smart, conditional, and reusable.

Understanding Control Flow in Bash

At its core, programming is just telling a computer how to make decisions and repeat tasks. In the shell, we use "control flow" structures to achieve this.

1. Conditional Logic with If-Statements

An if statement checks a condition and executes code only if that condition is true. In Bash, we use the [ ... ] syntax (a shorthand for the test command) to evaluate expressions.

Bash
#!/bin/bash
# Check if a directory exists
if [ -d "/var/www/html" ]; then
    echo "Web directory found."
else
    echo "Web directory missing!"
fi

Note: Always leave spaces inside the brackets—[ -d ... ]—or the shell will throw an error.

2. Handling Script Arguments

You don't want to hardcode every value. By using arguments, your scripts become generic tools. Bash assigns arguments to special variables:

  • $1, $2, etc.: The first, second, and subsequent arguments.
  • $#: The total number of arguments provided.

3. Looping Through Tasks

When you need to perform the same action on multiple items (like checking several log files), use a for loop.

Bash
# Loop through a list of files
for logfile in /var/log/nginx/*.log; do
    echo "Processing $logfile..."
    # Perform logic here
done

Worked Example: A Server Health Auditor

Let’s advance our running project. We need a script that checks if our web server files exist and reports their status. We'll use arguments to allow the user to specify which directory to check.

Create a file named check_server.sh:

Bash
#!/bin/bash

# Ensure an argument was provided
if [ $# -eq 0 ]; then
    echo "Usage: $0 <directory_path>"
    exit 1
fi

TARGET_DIR=$1

# Check if the target is actually a directory
if [ -d "$TARGET_DIR" ]; then
    echo "Scanning $TARGET_DIR for content..."
    
    # Loop through files in the directory
    for item in "$TARGET_DIR"/*; do
        if [ -f "$item" ]; then
            echo "Found file: $(basename "$item")"
        fi
    done
else
    echo "Error: $TARGET_DIR is not a valid directory."
    exit 1
fi

Make it executable with chmod +x check_server.sh and run it: ./check_server.sh /var/www/html.

Hands-on Exercise

Modify the check_server.sh script above to perform one additional check: if the directory is empty, print a message saying "No content found" instead of just finishing silently. Use the ls -A command combined with a conditional to detect if the directory contains any files.

Common Pitfalls

  • Missing Quotes: Always wrap variables in double quotes (e.g., "$TARGET_DIR") to handle paths with spaces safely.
  • The Exit Code: Every script should return an exit code. Use exit 0 for success and exit 1 (or higher) for errors.
  • Shebang Omission: Never forget the #!/bin/bash at the top of your file; without it, the script might run in a different shell, causing syntax errors.

Frequently Asked Questions

Q: Why use [ ... ] instead of just running commands? A: [ ... ] (the test command) allows you to check file states, string equality, and numeric comparisons, which are essential for robust automation.

Q: Can I nest if-statements inside loops? A: Yes, absolutely. You can nest structures as deeply as needed to create complex logic.

Q: What is $0 in the script? A: $0 refers to the name of the script itself, which is useful for printing usage instructions.

Recap

We’ve learned to move beyond static commands into dynamic logic. By using if to make decisions, for to iterate over lists, and positional arguments to accept user input, you've gained the foundation needed to write professional-grade automation. You are no longer just running commands; you are building tools.

Up next: Advanced Redirection and Pipes

Similar Posts