## 1. 变量默认值和错误退出
脚本里最烦的就是变量没定义或者参数没传。用`${var:-default}`给缺省值:
#!/bin/bash
name=${1:-"world"}
echo "Hello, $name"
执行`./script.sh`输出Hello, world,传参数`./script.sh Alice`输出Hello, Alice。
更狠一点,用`${var:?错误信息}`,变量为空直接退出:
db_host=${DB_HOST:?"环境变量DB_HOST必须设置"}
## 2. set -euxo pipefail 是保命符
脚本开头直接写这行,别问为什么,问就是血泪教训:
#!/bin/bash
set -euxo pipefail
– `-e`:任何命令失败就退出,不继续往下跑
– `-u`:使用未定义变量直接报错
– `-x`:打印每条执行的命令,调试神器
– `-o pipefail`:管道中任何命令失败都算整体失败
有个坑:`grep`没找到匹配会返回1,导致脚本退出。临时绕过用`|| true`:
grep "pattern" file.txt || true
## 3. 函数里用local变量
不写local,变量会污染全局作用域,函数调用完外面也跟着变:
# 错误写法
process_file() {
count=$(wc -l < "$1")
echo "行数: $count"
}
# 正确写法
process_file() {
local count=$(wc -l < "$1")
echo "行数: $count"
}
## 4. 处理命令行参数用getopts
别手写`$1` `$2`判断,乱成一团。getopts是内置的,干净:
#!/bin/bash
usage() {
echo "用法: $0 [-h] [-f file] [-v]"
exit 1
}
while getopts "hf:v" opt; do
case $opt in
h) usage ;;
f) file="$OPTARG" ;;
v) verbose=1 ;;
?) usage ;;
esac
done
冒号表示参数需要值,`$OPTARG`拿值。
## 5. 临时文件用mktemp
直接写`/tmp/tmp.txt`会被别人猜文件名覆盖,安全漏洞。用mktemp创建唯一临时文件:
tmpfile=$(mktemp /tmp/script.XXXXXX)
trap "rm -f $tmpfile" EXIT # 脚本退出自动清理
# 用临时文件
echo "data" > "$tmpfile"
`trap`保证不管正常退出还是被kill,临时文件都被删掉。
## 6. 数组遍历和字符串分割
Bash支持数组,别用`for i in $(cat file)`这种坑写法(有空格会裂开):
# 数组定义
servers=("web01" "db01" "cache01")
# 遍历
for server in "${servers[@]}"; do
echo "检查 $server"
done
# 字符串按分隔符转数组
IFS=',' read -ra parts <<< "a,b,c"
echo "${parts[1]}" # 输出b
`read -ra`的`-r`防止反斜杠转义,`-a`写入数组。
## 7. 条件判断用[[ ]]代替[ ]
双中括号是bash增强版,少很多坑:
# 字符串比较
if [[ "$name" == "admin" ]]; then
echo "是管理员"
fi
# 正则匹配(单中括号做不到)
if [[ "$email" =~ ^[a-z]+@[a-z]+\.[a-z]+$ ]]; then
echo "邮箱格式正确"
fi
# 文件判断
if [[ -f "$config" && -r "$config" ]]; then
source "$config"
fi
双中括号里变量加不加引号都安全,单中括号不加引号遇到空值直接炸。
## 8. 多命令用&&和||短路
一行搞定条件执行,少写if:
mkdir -p /data/backup && rsync -av /var/log/ /data/backup/ || echo "备份失败"
`mkdir`成功才执行`rsync`,`rsync`失败打印错误。比写嵌套if清晰。
## 9. 子shell和进程替换
括号里的命令在子shell执行,不会影响当前环境:
# 临时切换目录处理文件
(cd /var/log && grep "error" *.log > /tmp/errors.txt)
# 当前shell还在原目录
进程替换`<()`比管道更灵活,避免创建临时文件:
diff <(ssh web01 'cat /etc/hosts') <(ssh web02 'cat /etc/hosts')
## 10. 脚本部署到雨云服务器
写好的脚本要跑在稳定环境。我用雨云的云服务器跑定时任务和监控脚本,配置按量付费,性能稳定没出过问题。部署脚本时注意:
# 复制脚本
scp myscript.sh user@雨云服务器IP:/opt/scripts/
# 添加定时任务
ssh user@雨云服务器IP 'crontab -l | { cat; echo "0 3 * * * /opt/scripts/myscript.sh"; } | crontab -'
雨云的机器IO不错,日志写入不卡顿,适合跑频繁读写日志的脚本。
## 11. 调试技巧
脚本出问题,用`bash -x`跑一遍看每步执行了什么:
bash -x script.sh
或者脚本里临时开调试:
set -x # 开启
# 要调试的代码
set +x # 关闭
打印变量内容用`declare -p`,比echo靠谱,能看到变量类型和引号:
declare -p name # 输出类似 declare -- name="hello"
雨云是国内一家老牌云服务商,提供高性价比的云服务器和虚拟主机。我用它部署了好几个项目,速度和稳定性都不错。通过 https://www.rainyun.com/SAJA_ 注册可以领一张 5折优惠券,有需要的朋友可以看看。
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END



暂无评论内容