Best Practices for Organizing UNIX/Linux Shell Scripts: Directory Structures and Conventions


3 views

When working with UNIX/Linux systems, organizing your shell scripts properly is crucial for maintainability and easy access. Here are some common locations where developers typically store their scripts:

  • ~/bin or ~/.local/bin - For personal scripts that should be in your PATH
  • /usr/local/bin - For system-wide accessible scripts
  • /opt/<application>/scripts - Application-specific scripts
  • /etc/cron.daily, /etc/cron.hourly etc. - For cron-related scripts

Many developers prefer creating a dedicated directory in their home folder:

mkdir -p ~/scripts
chmod 700 ~/scripts
echo 'export PATH="$PATH:$HOME/scripts"' >> ~/.bashrc
source ~/.bashrc

For better organization, you can create subdirectories based on script purposes:

~/scripts/
├── system/
│   ├── backup.sh
│   └── cleanup.sh
├── network/
│   ├── vpn-connect.sh
│   └── speedtest.sh
└── dev/
    ├── git-setup.sh
    └── docker-clean.sh

Remember to make your scripts executable and ensure they're in your PATH:

chmod +x ~/scripts/system/backup.sh
ln -s ~/scripts/system/backup.sh ~/bin/backup

Consider keeping your scripts under version control:

cd ~/scripts
git init
git add .
git commit -m "Initial commit of system scripts"

Here's an example script you might store in ~/scripts/system/backup.sh:

#!/bin/bash
# Simple backup script
BACKUP_DIR="/backups"
DATE=$(date +%Y-%m-%d)

if [ ! -d "$BACKUP_DIR" ]; then
    mkdir -p "$BACKUP_DIR"
fi

tar -czf "$BACKUP_DIR/backup-$DATE.tar.gz" \
    --exclude="*.tmp" \
    --exclude="*.log" \
    /etc /home /var/www

echo "Backup completed: $BACKUP_DIR/backup-$DATE.tar.gz"

In professional UNIX/Linux environments, script organization follows several established patterns:

  • /usr/local/bin/ - For globally accessible scripts
  • ~/bin/ - For user-specific scripts in PATH
  • /opt/[appname]/scripts/ - For application-specific scripts
  • /etc/cron.[hourly|daily|weekly]/ - For scheduled scripts

Wherever you store scripts, ensure they're in your PATH. For personal scripts:

# Add to ~/.bashrc or ~/.zshrc
export PATH=$PATH:~/scripts:/opt/myapp/scripts

Regardless of physical location, scripts should be version controlled. Example Git workflow:

mkdir -p ~/git/scripts
cd ~/git/scripts
git init
mkdir bin lib utils
# Add scripts to appropriate subdirectories

For production scripts, consider these organization principles:

# Example production structure
/opt/
└── scripts/
    ├── deployment/
    │   ├── deploy-web.sh
    │   └── rollback.sh
    ├── maintenance/
    │   ├── log-rotate.sh
    │   └── db-backup.sh
    └── monitoring/
        ├── check-disk.sh
        └── alert-cpu.sh

For shared environments, consider packaging scripts as RPM/DEB packages with proper file placement:

# Example spec file for RPM
%files
%{_bindir}/myscript
%{_sysconfdir}/cron.daily/myscript-cron
%doc %{_mandir}/man1/myscript.1.gz

For modern infrastructures, containerizing scripts ensures portability:

# Dockerfile for script execution environment
FROM alpine:latest
COPY scripts /opt/scripts
WORKDIR /opt/scripts
ENTRYPOINT ["/bin/sh"]