Bash Scripting Essentials
Skeleton for every script
#!/usr/bin/env bash
set -euo pipefail
IFS=$'\n\t'
main() {
echo "Hello from $(hostname)"
}
main "$@"
-eexit on error,-uerror on unset variables,-o pipefailfail if any command in a pipe fails.main "$@"passes all arguments through, keeping the script readable top to bottom.
Variables and quoting
name="PandaDev" # no spaces around =
echo "Hello $name" # double quotes expand variables
echo 'Hello $name' # single quotes are literal
files=$(ls *.log) # command substitution
count=$((3 + 4)) # arithmetic
echo "${name,,}" # lowercase: pandadev
echo "${FILE:-default.txt}" # default value if unset
Quote every variable: "$file", not $file. Unquoted variables split on spaces and expand wildcards, which is how scripts delete the wrong files.
Conditions
if [[ -f "$config" ]]; then
echo "config exists"
elif [[ -d "$config" ]]; then
echo "that is a folder"
else
echo "missing" >&2
exit 1
fi
| Test | True when |
|---|---|
-f file |
regular file exists |
-d dir |
directory exists |
-z "$s" |
string is empty |
"$a" == "$b" |
strings are equal |
$n -gt 5 |
number greater than 5 (-lt, -eq, -ge...) |
Loops
for f in /var/log/nginx/*.log; do
echo "$f: $(wc -l < "$f") lines"
done
while read -r line; do
echo "user: $line"
done < users.txt
for i in {1..5}; do echo "attempt $i"; done
Functions and arguments
log() { echo "[$(date -u +%H:%M:%S)] $*"; }
usage() {
echo "Usage: $0 <environment> [--dry-run]" >&2
exit 2
}
[[ $# -ge 1 ]] || usage
env="$1"
dry_run=false
[[ "${2:-}" == "--dry-run" ]] && dry_run=true
log "deploying to $env (dry run: $dry_run)"
$1, $2... are arguments, $# is how many, $@ is all of them.
Cleaning up, even on failure
tmp=$(mktemp -d)
trap 'rm -rf "$tmp"' EXIT
trap ... EXIT runs when the script ends for any reason, so temporary files never pile up.
Check your scripts
Install ShellCheck (sudo apt install shellcheck) and run shellcheck script.sh. It catches unquoted variables and dozens of other bugs before they run.
Exercise
Write disk-alert.sh that prints a warning to stderr and exits with code 1 when any filesystem in df -P is above a percentage given as the first argument (default 80).
आपकी प्रगति केवल इसी ब्राउज़र में सहेजी जाती है।
समीक्षा के लिए भेजें (10 अंक)