實用範例
下面幾支腳本都刻意保持短。建議自己打一遍、改路徑、故意給錯參數,看它如何失敗。
備份一個目錄
#!/usr/bin/env bash
set -euo pipefail
src=${1:-$HOME/linux-lab}
dest_dir=${2:-$HOME/backups}
stamp=$(date +%F_%H%M)
mkdir -p "$dest_dir"
archive="$dest_dir/$(basename "$src")-$stamp.tar.gz"
tar -czf "$archive" -C "$(dirname "$src")" "$(basename "$src")"
echo "已寫入 $archive"
可搭配 crontab 每天跑。tar -C 先 cd 到上層,封包裡就不會帶一長串絕對路徑。
磁碟使用率超過門檻就警告
#!/usr/bin/env bash
set -euo pipefail
threshold=${1:-80}
used=$(df -P / | awk 'NR==2 {print $5}' | tr -d '%')
if (( used >= threshold )); then
echo "警告:根目錄已使用 ${used}%" >&2
exit 1
fi
echo "根目錄使用 ${used}%,低於 ${threshold}%"
df -P 保證一行一個檔案系統,方便用 awk 切欄。結束碼非 0 時,cron 或監控比較容易察覺。
等服務聽上埠才繼續
#!/usr/bin/env bash
set -euo pipefail
port=${1:-8080}
for i in {1..30}; do
if ss -tln | grep -q ":${port} "; then
echo "port $port 已在聽"
exit 0
fi
sleep 1
done
echo "等了 30 秒,$port 仍未開啟" >&2
exit 1
部署腳本常需要「服務起來再跑下一關」。更完整可用 systemctl is-active 判斷 systemd 服務。
批次把副檔名改小寫
#!/usr/bin/env bash
set -euo pipefail
shopt -s nullglob
dir=${1:-.}
cd "$dir"
for f in *.JPG *.JPEG *.PNG; do
[[ -f $f ]] || continue
ext=${f##*.}
base=${f%.*}
mv -- "$f" "${base}.${ext,,}"
done
${f##*.} 取最後一個副檔名,${ext,,} 轉小寫(Bash 4+)。-- 避免檔名以 - 開頭時被當成選項。
安全習慣清單
- 變數加雙引號;路徑用絕對路徑(尤其 cron)
- 破壞性動作先
echo印出將要執行的指令,確認再拿掉 echo - 需要 root 時在腳本開頭檢查
id -u,不要假設使用者會加 sudo - 把 log 導向檔案:
exec > >(tee -a "$log") 2>&1進階再學,入門用>> log 2>&1即可
總結
備份、看磁碟、等埠、改檔名,已經涵蓋腳本最常見的四種工作:封存、檢查、等待、批次改檔。指令層的基礎在前面各章;這裡只是把它們串起來。