Bash脚本编写实用技巧合集

## 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
喜欢就支持一下吧
点赞9 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容