Skip to content

Code_style

This chapter covers how to organize and style bash scripts for better maintainability, readability, and collaboration.


project/
├── bin/
│ ├── main.sh
│ └── functions.sh
├── lib/
│ ├── config.sh
│ └── utils.sh
├── conf/
│ └── app.conf
├── logs/
└── README.md
/usr/local/bin/ # User scripts
/etc/scripts/ # System scripts
/opt/app/bin/ # Application scripts
~/scripts/ # Personal scripts

Terminal window
# Use descriptive names
deploy.sh
backup_database.sh
monitor_services.sh
# Avoid abbreviations (except well-known)
nginx_conf.sh # OK
ng_c.sh # Not good
# Use kebab-case or snake_case
deploy.sh # kebab-case
deploy_script.sh # snake_case
Terminal window
# Constants - UPPERCASE
readonly MAX_RETRIES=3
readonly DEFAULT_PORT=8080
# Variables - lowercase
local count=0
local input_file=""
# Arrays - plural or suffix
local files=()
local file_list=()
# Associative arrays - descriptive
declare -A user_config
declare -A server_ports
Terminal window
# Use descriptive names
check_service_health()
deploy_application()
backup_database()
# Use verb-noun pattern
deploy()
install()
update()

Terminal window
# Use 4 spaces (not tabs)
function example() {
if [[ condition ]]; then
echo "Hello"
fi
}
Terminal window
# Keep lines under 80 characters
# Break long commands
curl -X POST \
-H "Content-Type: application/json" \
-d '{"key": "value"}' \
http://api.example.com/endpoint
# Use variables for long values
readonly API_ENDPOINT="http://api.example.com/v1"
curl -X POST "$API_ENDPOINT/endpoint"
Terminal window
# Spaces around operators
local sum=$((a + b))
local result="${var//old/new}"
# No spaces in tests
if [[ $a -eq $b ]]; then
echo "Equal"
fi
# Spaces after commas
array=(one two three)
local item="${array[0]}"

#!/bin/bash
#
# Script description
#
# Author: Your Name
# Version: 1.0.0
#
# Section comments
# ==================
# Configuration
# ==================
# Function comments
# process_file - Processes input file
# Arguments:
# $1 - input file path
# Returns:
# 0 on success, 1 on failure
process_file() {
# Inline comments
local file="$1" # Input file
}
# TODO comments
# TODO: Add error handling
# FIXME: Fix this bug

Terminal window
# Put main function at the bottom
# Put helper functions first
# Order:
# 1. Imports/source files
# 2. Global variables
# 3. Helper functions
# 4. Main functions
# 5. Entry point
# Example order:
# source lib/utils.sh
# readonly CONFIG_FILE="..."
# log()
# error()
# cleanup()
# deploy()
# backup()
# restore()
# main()
main "$@"
Terminal window
# Standard function template
function_name() {
# Description comment
# Arguments
local arg1="$1"
local arg2="${2:-default}"
# Local variables
local result=""
# Function body
if condition; then
result="value"
fi
# Return value or status
echo "$result"
return 0
}

#!/bin/bash
# Test runner
run_test() {
local test_name="$1"
local test_func="$2"
echo -n "Testing: $test_name... "
if $test_func; then
echo "PASS"
((PASSED++))
else
echo "FAIL"
((FAILED++))
fi
}
# Test functions
test_example() {
[[ $(echo "hello" | tr 'a-z' 'A-Z') == "HELLO" ]]
}
# Run tests
run_test "Example test" test_example

Terminal window
# .gitignore for bash projects
# Logs
*.log
logs/
# Temporary files
*.tmp
*.swp
*~
# Backups
*.bak
*.backup
# Secrets
.env
*.pem
*.key
# Build output
build/
dist/
feat: Add deployment script
fix: Fix backup rotation
docs: Update README
refactor: Simplify config loading
test: Add unit tests

Terminal window
# README.md
# Project Name
Short description
## Installation
\`\`\`bash
./install.sh
\`\`\`
## Usage
\`\`\`bash
./script.sh -f input.txt
\`\`\`
## Configuration
Set these environment variables:
- VAR_NAME: Description
## License
MIT

Terminal window
# Install
sudo pacman -S shellcheck
# Run
shellcheck script.sh
# With options
shellcheck -x script.sh # Allow source
shellcheck -e SC1090 script.sh
Terminal window
# Install
go install mvdan.cc/sh/v3/cmd/shfmt@latest
# Format
shfmt -w script.sh
# With options
shfmt -l -w -i 4 script.sh

  • Use descriptive names
  • Comment complex code
  • Keep functions small and focused
  • Use strict mode
  • Test your scripts
  • Use version control
  • Don’t use one-letter variables
  • Don’t hardcode secrets
  • Don’t use deprecated syntax
  • Don’t ignore shellcheck warnings
  • Don’t write spaghetti code

In this chapter, you learned:

  • ✅ Code organization (directories, scripts)
  • ✅ Naming conventions (files, variables, functions)
  • ✅ Code layout (indentation, line length, spacing)
  • ✅ Commenting best practices
  • ✅ Function organization
  • ✅ Testing framework
  • ✅ Version control and .gitignore
  • ✅ README documentation
  • ✅ Tools (shellcheck, shfmt)

Continue to the next chapter to learn about System Administration Scripts.


Previous Chapter: Common One-liners Next Chapter: System Administration Scripts