Bash 脚本指南
脚本头部与错误处理
#!/usr/bin/env bash
set -euo pipefail
IFS=$'\n\t'
# set -e : 任意命令出错即退出
# set -u : 未设置变量则报错
# set -o pipefail : 管道中任意命令失败则整体失败
# 清理陷阱
cleanup() {
echo "清理中..."
rm -f /tmp/myapp.lock
}
trap cleanup EXIT
trap 'echo "第 $LINENO 行发生错误"; exit 1' ERR
# 日志函数
log() { echo "[$(date '+%Y-%m-%d %H:%M:%S')] INFO: $*"; }
warn() { echo "[$(date '+%Y-%m-%d %H:%M:%S')] WARN: $*" >&2; }
err() { echo "[$(date '+%Y-%m-%d %H:%M:%S')] ERROR: $*" >&2; }
变量
# 变量赋值(等号两侧无空格)
name="Alice"
count=42
# 默认值
app_name="${APP_NAME:-myapp}" # 未设置则使用默认值
db_host="${DB_HOST:?'DB_HOST 为必填项'}" # 未设置则报错
# 变量展开
echo "${name^^}" # 转大写
echo "${name,,}" # 转小写
echo "${name:0:3}" # 子字符串(起始位置,长度)
echo "${name/Alice/Bob}" # 替换第一个匹配
echo "${#name}" # 字符串长度
# 算术运算
x=$((10 + 5))
echo $(( 2**10 )) # 1024
条件判断
# if / elif / else
if [[ -f /etc/nginx/nginx.conf ]]; then
echo "nginx 已安装"
elif [[ -z "$DB_HOST" ]]; then
echo "DB_HOST 未设置"
fi
# case 语句
case "$1" in
start) systemctl start myapp ;;
stop) systemctl stop myapp ;;
restart) systemctl restart myapp ;;
*) echo "用法: $0 {start|stop|restart}"; exit 1 ;;
esac
循环
# 遍历列表
for server in web1 web2 web3; do
ssh "$server" "sudo systemctl restart myapp"
done
# 范围循环
for i in {1..10}; do echo "Item $i"; done
# 按行读取文件
while IFS= read -r line; do
echo "处理: $line"
done < /etc/hosts
# 等待服务就绪
until curl -sf http://localhost:8080/health; do
echo "等待服务..."
sleep 2
done
函数
deploy_app() {
local app_name="$1"
local version="${2:-latest}"
local env="${3:-dev}"
log "部署 ${app_name}:${version} 到 ${env}"
[[ -z "$app_name" ]] && { err "app_name 为必填项"; return 1; }
return 0
}
deploy_app "myapp" "v2.1.0" "production" && log "部署成功" || { err "部署失败"; exit 1; }