0Pricing
DevOps Bootcamp · Lesson

Scripting Best Practices & Linting

Learn about coding conventions, commenting, and using tools like ShellCheck to write clean, readable, and error-free Bash scripts.

Scripting Best Practices & Linting is a free DevOps Bootcamp lesson on CoddyKit — lesson 3 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the DevOps Bootcamp learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.

Why Scripting Best Practices?

Writing Bash scripts is powerful, but without good habits, scripts can become hard to understand, maintain, and debug.

Best practices are guidelines that help you write clean, robust, and readable code. They make your scripts:

  • Easier to Read: For yourself and others.
  • More Maintainable: Simpler to update or fix.
  • Less Error-Prone: Preventing common mistakes.
  • Better for Collaboration: Standardizing how code looks and behaves.

Commenting for Clarity

Comments are crucial for explaining why your code does something, not just what it does. They act as notes for future you or other developers.

Use comments to:

  • Describe the script's overall purpose at the top.
  • Explain complex logic or tricky sections.
  • Document functions: their purpose, arguments, and return values.

Start a comment with a # (hash) symbol.

#!/bin/bash
# This script demonstrates commenting best practices.
# Author: CoddyKit
# Date: 2023-10-27

# Function: greet_user
# Description: Prints a greeting message to the console.
# Arguments:
#   $1 - The name of the user to greet.
greet_user() {
  local name="$1" # Store the first argument in a local variable.
  echo "Hello, ${name}!" # Output the greeting message.
}

# Main script execution starts here.
echo "Script execution started."
greet_user "CoddyKit Learner" # Call the function with a specific name.
echo "Script execution finished."

Clear Naming Conventions

Meaningful names make your script easier to follow. Avoid single-letter variables unless they're common loop counters (like i or j).

General conventions:

  • Variables: Use descriptive names (e.g., user_name, log_file). Use UPPERCASE for environment variables or global constants. Use lowercase_with_underscores for local script variables.
  • Functions: Use lowercase_with_underscores, often starting with a verb (e.g., process_data, check_status).
  • Scripts: Use lowercase_with_hyphens (e.g., backup-script.sh).

Consistent Formatting & Indentation

Consistent formatting, like indentation and spacing, dramatically improves readability. Imagine reading a book with inconsistent paragraph indents!

Key points:

  • Use 2 or 4 spaces for indentation (tabs are often discouraged).
  • Keep lines short (under 80 characters is a good rule of thumb for terminals).
  • Use blank lines to separate logical blocks of code.
  • Align related elements where it makes sense.

Consistency is more important than the specific style you choose.

Robustness: 'set -u' (nounset)

The set -u (or set -o nounset) option is a lifesaver for preventing bugs caused by typos or accidentally unset variables. If your script tries to use a variable that hasn't been assigned a value, set -u will immediately exit the script with an error.

This helps catch errors early, preventing unexpected behavior later in your script.

Try running the code below. It's designed to exit early because UNSET_NAME is not defined.

#!/bin/bash
# Demonstrating 'set -u' (nounset)

set -u # Exit if an unset variable is used

MY_GREETING="Hello"
echo "${MY_GREETING}, CoddyKit!"

# This variable is NOT set. With 'set -u', the script will exit here.
echo "Your name is: ${UNSET_NAME}" 

echo "This line will NOT be reached if 'set -u' is active and UNSET_NAME is indeed unset."

Robustness: 'set -o pipefail'

When you pipe commands (e.g., cmd1 | cmd2 | cmd3), Bash normally only reports the exit status of the last command in the pipe. This means if cmd1 fails, but cmd2 and cmd3 succeed, the pipe might still report success!

set -o pipefail changes this behavior. If any command in a pipe fails (returns a non-zero exit status), the entire pipe's exit status will be that non-zero status.

This makes your pipelines more reliable by immediately signaling if an early command failed.

#!/bin/bash
# Demonstrating 'set -o pipefail'

set -o pipefail # Ensures pipe's exit status is the last non-zero command

echo "Running a failing command in a pipe:"
echo "---"

# 'false' command always fails (exit status 1).
# 'cat /dev/null' always succeeds (exit status 0).
# With 'set -o pipefail', the pipe's overall exit status will be 1 from 'false'.
false | cat /dev/null

# This line will only be reached if the pipe above succeeds.
echo "---"
echo "Script finished successfully (this line won't show if pipe failed with set -o pipefail)."

Introducing ShellCheck

Even with best practices, it's easy to overlook small syntax errors or common pitfalls. That's where ShellCheck comes in!

ShellCheck is a static analysis tool (a 'linter') for shell scripts. It reads your script and points out:

  • Syntax errors.
  • Common beginner mistakes.
  • Subtle semantic problems.
  • Portable issues across different shells.

It gives you helpful suggestions, often with links to more detailed explanations.

ShellCheck in Action: Bad Script

Let's look at a script with a few common issues. These might not cause the script to crash immediately, but they are bad practices or potential bugs.

Imagine you have this script saved as bad_script.sh. To run ShellCheck on it, you'd type: shellcheck bad_script.sh

See if you can spot the issues before running ShellCheck!

#!/bin/bash
# A script with some common issues

MY_NAME=coddykit # Variable assignment needs no space, but quoting is good for values
echo "Hello $MY_NAME!" # Missing quotes around variable expansion

if [ $1 = "admin" ]; then # Missing quotes around $1
  echo "Welcome, administrator."
fi

# A simple loop with potential issues
for file in *.txt; do # Unquoted glob could expand to multiple arguments
  echo File: $file # Missing quotes around $file
done

Fixing ShellCheck Warnings

ShellCheck would provide output like: SC2086: Double quotes missing around "$MY_NAME". It often gives a specific code (like SC2086) that you can look up for more details.

Here's the previous script, fixed according to ShellCheck's recommendations and general best practices:

Notice the use of double quotes "" around variable expansions and command substitutions to prevent word splitting and globbing, which are common sources of bugs.

#!/bin/bash
# A script with issues fixed by ShellCheck

MY_NAME="CoddyKit" # Quote variable assignment values
echo "Hello ${MY_NAME}!" # Always quote variable expansions

if [ "$1" = "admin" ]; then # Quote positional parameters like $1
  echo "Welcome, administrator."
fi

# A simple loop with corrected quoting
for file in *.txt; do 
  echo "File: ${file}" # Quote variable expansions, especially in loops
done

Best Practices Check

Which of the following are considered good practices when writing Bash scripts?

Recap: Professional Scripting

Congratulations! You've learned how to elevate your Bash scripts from functional to professional.

We covered:

  • The importance of best practices for readability and maintainability.
  • Using comments and naming conventions for clarity.
  • Making scripts robust with set -u and set -o pipefail.
  • The power of ShellCheck to automatically find issues and improve your code.

By applying these principles, you'll write more reliable, understandable, and collaborative Bash scripts. Keep practicing!

Frequently asked questions

Is the “Scripting Best Practices & Linting” lesson free?

Yes — the full text of “Scripting Best Practices & Linting” is free to read here on the web, and the DevOps Bootcamp course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the DevOps Bootcamp course, upgrade to CoddyKit PRO.

What will I learn in “Scripting Best Practices & Linting”?

Learn about coding conventions, commenting, and using tools like ShellCheck to write clean, readable, and error-free Bash scripts. You practise DevOps Bootcamp with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.

Do I need any experience to start DevOps Bootcamp?

No prior experience is required. DevOps Bootcamp on CoddyKit is structured for beginners through advanced learners; this is — lesson 3 of 4, so you can start here or from the beginning and move at your own pace.

How long does the “Scripting Best Practices & Linting” lesson take?

Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.

Can I write and run code in this DevOps Bootcamp lesson?

Yes. Every DevOps Bootcamp lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.

All lessons in this course

  1. Debugging Bash Scripts (set -x, trap)
  2. Error Handling & Exit Status
  3. Scripting Best Practices & Linting
  4. Testing Bash Scripts with Bats
← Back to DevOps Bootcamp