Introduction to Linux Shell (Part 14): Modularization and Project Structure Design of Shell Scripts

Chapter Objective: Master the structured organization of large Shell projects to enhance script engineering capabilities.

1. Why Modularization and Structuring?

As the size of scripts increases:

  • Maintenance of single files becomes difficult

  • Repeated development of different functionalities

  • Lack of reusability and configurability

  • Difficulties in debugging and collaboration

Modularization and structuring can solve these problems, allowing scripts to be developed and maintained like programs.

2. Typical Shell Project Structure

my-shell-project/
├── bin/                # Executable scripts
│   └── backup.sh
├── lib/                # Common function library
│   ├── config.sh
│   └── utils.sh
├── logs/               # Log file storage
├── conf/               # Configuration files
│   └── backup.conf
├── tmp/                # Temporary data
├── README.md           # Project description
└── run.sh              # Main entry script

3. Basics of Modularization: Function Libraries and Configuration

1. Write a General Function Module (lib/utils.sh)

log() {
  echo "[$(date '+%F %T')] $1"
}

2. Write a Configuration Module (lib/config.sh)

BACKUP_SRC="/home/user/data"
BACKUP_DST="/backup"

3. Load Modules in the Main Script

#!/bin/bash
BASE_DIR="$(cd "$(dirname "$0")" && pwd)"
source "$BASE_DIR/lib/config.sh"
source "$BASE_DIR/lib/utils.sh"

log "Starting backup..."
# Business logic

4. Decoupling Configuration Files and Parameters

Parameters can be extracted into a <span>.conf</span> configuration file for easier modification and multi-environment deployment.

Example Configuration File (conf/backup.conf):

SRC_DIR="/home/user/data"
DST_DIR="/mnt/backup"

Read Configuration File:

source ./conf/backup.conf

5. Supporting Command Parameters and Subcommands (Advanced)

case "$1" in
  backup)
    ./bin/backup.sh
    ;;
  clean)
    ./bin/clean.sh
    ;;
  *)
    echo "Usage: $0 {backup|clean}"
    exit 1
    ;;
esac

6. Adding Logging Mechanism and Error Handling

LOG_FILE="./logs/backup_$(date +%F).log"
exec > >(tee -a "$LOG_FILE") 2>&1

trap 'echo "[ERROR] Execution failed: $BASH_COMMAND"' ERR

7. Adding Makefile (Optional)

To unify the execution entry, a Makefile can be created:

run:
	bash run.sh backup

clean:
	rm -rf tmp/*

Run Command:

make run

8. Version Control and Team Collaboration

Use Git to manage Shell projects:

git init
echo "logs/" >> .gitignore

Team Collaboration:

  • Each person maintains a module or functionality

  • Use Pull Requests for review and merging

  • Maintain readability with comments and README documentation

9. Reference Cases of Well-Structured Shell Projects

The clearer the project directory structure, the easier it is to maintain and expand.

✅ Recommended Reading:

  • bash boilerplate

  • bashly (Command Line Builder)

10. Summary: Recommendations for Writing Professional Shell Engineering

Recommendation Description
Split Logic into Function Modules Each functionality as a separate library file
Externalize Configuration Parameters <span>.conf</span> files for centralized management
Add Logging and Error Handling Improve traceability
Provide Unified Entry and Usage Instructions <span>run.sh</span> + <span>README.md</span>
Use Git for Management and Collaboration Project specifications + version control
Keep it Simple and Readable Avoid deep nesting, clear naming

✅ Next Article Preview:

Introduction to Linux Shell (Part 15): Security and Best Practices of Shell Scripts

This will explain how to prevent scripts from accidentally deleting files, leaking permissions, and preventing injections, ensuring the secure operation of scripts.

Leave a Comment