跳轉到

建立 2026-09-14 更新 2026-09-14

實用範例

下面幾支腳本都刻意保持短。建議自己打一遍、改路徑、故意給錯參數,看它如何失敗。

備份一個目錄

#!/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 即可

總結

備份、看磁碟、等埠、改檔名,已經涵蓋腳本最常見的四種工作:封存、檢查、等待、批次改檔。指令層的基礎在前面各章;這裡只是把它們串起來。