Bash is a foundational shell for Linux and Unix-like systems. This section focuses on practical scripting patterns that are reliable in automation workflows and easy to maintain over time.
What You Will Find Here
- Script structure and safety defaults for predictable execution
- Input validation and defensive parameter handling
- Quoting, globbing, and whitespace-safe file processing
- Logging, exit codes, and troubleshooting patterns
- SSH-centric automation patterns (SCP, SFTP, rsync)
Command References
- Navigation and File Commands
- Text Processing and Search Commands
- System, Process, and Network Commands
Getting Started
Use this script template as a baseline for most automation jobs.
This template gives you a safe default structure for production scripts. It separates helper logic from execution flow, enables strict error handling, and preserves command-line arguments exactly as they were provided.
#!/usr/bin/env bash
set -euo pipefail
log() {
printf '[%s] %s\n' "$(date +'%Y-%m-%d %H:%M:%S')" "$*"
}
main()
{
log "Starting task"
}
main "$@"
Detailed explanation:
#!/usr/bin/env bashselects Bash from the current environment so the script runs correctly across systems where Bash may be installed in different locations.set -euo pipefailenables strict mode:-estops execution when a command fails.-utreats unset variables as errors.pipefailmakes pipelines fail if any command in the chain fails.
log()is a reusable helper that prints timestamped messages in a consistent format, which improves traceability in CI jobs and cron logs.main()isolates the primary workflow in one place, which makes the script easier to test, read, and extend.main "$@"forwards all original arguments safely tomainwithout breaking on spaces or special characters.
Bash Safety Essentials
- Use strict mode (
set -euo pipefail) for scripts that should fail fast. - Quote variable expansions:
"${Variable}". - Prefer
[[ ... ]]for tests over[ ... ]. - Use functions for reusable logic and easier testing.
- Return non-zero exit codes on failure and log useful context.
Common Automation Patterns
Iterate Over Files Safely
find /var/log -type f -name '*.log' -print0 |
while IFS= read -r -d '' FilePath
do
printf 'Processing %s\n' "$FilePath"
done
Detailed explanation:
find /var/log -type f -name '*.log' -print0discovers matching files and emits null-delimited paths instead of newline-delimited paths.- Null-delimited output is important because file names can legally contain spaces, tabs, or newlines.
while IFS= read -r -d '' FilePathreads one null-delimited entry at a time:IFS=preserves leading and trailing whitespace.-rdisables backslash escaping so paths are read literally.-d ''tellsreadto use the null byte as the delimiter.
printf 'Processing %s\n' "$FilePath"prints each path safely with quoting, avoiding word splitting and glob expansion.- This pattern is preferred over
for f in $(find ...)because command substitution breaks on whitespace and special characters.
Validate Inputs Early
if [[ $# -lt 1 ]]
then
echo "Usage: $0 <target-path>"
exit 1
fi
TargetPath="$1"
Detailed explanation:
[[ $# -lt 1 ]]checks whether fewer than one positional argument was provided.- The early guard clause fails fast with a usage message, which prevents the script from running in an invalid state.
echo "Usage: $0 <target-path>"prints a clear invocation format using$0(the script name) so users can quickly correct their command.exit 1returns a non-zero status to signal invalid input to calling tools, automation pipelines, or parent scripts.TargetPath="$1"stores the first argument in a named variable to improve readability and reduce mistakes in later logic.
Handle Command Failures Explicitly
if ! rsync -az --partial ./source/ user@host:/backup/source/
then
echo "Backup failed" >&2
exit 1
fi
Detailed explanation:
if ! rsync ...inverts the command result so thethenblock executes only on failure.rsync -az --partialuses common backup-friendly flags:-aenables archive mode (recursive copy with metadata preservation).-zcompresses data in transit, useful for remote transfers.--partialkeeps partially transferred files so interrupted transfers can resume more efficiently.
echo "Backup failed" >&2writes the error message to standard error, keeping diagnostic output separate from normal script output.exit 1surfaces failure immediately to schedulers and CI systems so they can alert or retry.- This explicit pattern is valuable even with strict mode because it lets you attach a clear, human-readable error message at the exact failure point.
Related Sections
- Linux for OS-level administration context
- PowerShell for cross-platform scripting alternatives
- Python for higher-level automation workflows