2025年12月19日/ 浏览 25
在Linux Shell脚本的王国里,if语句如同一位老练的守卫,而-a到-z这26个字母参数则是它手中神秘的钥匙串。这些看似简单的单字符参数,实则是脚本逻辑控制的基石。理解它们的本质,相当于掌握了Shell条件判断的密码本。
-a到-e的门卫哲学-a与-e这对孪生兄弟常被误认为等价,实则暗藏历史渊源:
bash
if [ -a /dev/null ]; then
echo “设备文件存在(兼容性写法)”
fi
if [ -e /tmp/lockfile ]; then
echo “文件或目录存在(现代首选)”
fi
深层差异:
– -a源自古老的Bourne Shell,对符号链接解析不稳定
– -e在Bash中更健壮,支持所有文件类型检测
文件权限三剑客-r(可读)、-w(可写)、-x(可执行)常被忽视的陷阱:
bash
if [ -w "$LOG_FILE" ]; then
# 即使文件只属于root,普通用户测试也可能返回true
# 实际写入时才会触发权限错误!
fi
解决方案:结合-n检查变量非空后,用touch预创建文件避免竞态条件。
-z与-n的空值博弈bash
username=””
if [ -z “$username” ]; then
echo “用户名为空!安全退出” >&2
exit 1
fi
if [ -n “${MAILBODY}” ]; then
sendemail “$MAIL_BODY”
fi
血泪教训:某次线上事故因未加引号导致[ -z $VAR ]在VAR为空时解析为[ -z ],反而返回true!永远包裹变量在双引号中。
-eq家族的精确艺术当比较数字时,-eq(等于)、-ne(不等于)、-gt(大于)等参数是唯一选择:
bash
disk_usage=90
if [ "$disk_usage" -gt 85 ]; then
echo "警告:磁盘空间不足!" | tee /dev/stderr
fi
经典错误:
bash
if [ "100" \> "90" ]; then # 按字典序比较,100<90因为1<9
if [ "100" -gt "90" ]; then # 正确数值比较
-t终端检测
bash
if [ -t 0 ]; then
echo "脚本在交互式终端运行"
else
echo "后台执行或管道输入"
fi
-O文件属主验证
bash
if [ -O ~/.ssh/id_rsa ]; then
chmod 600 ~/.ssh/id_rsa
fi
-N文件更新检测
bash
if [ -N /var/log/syslog ]; then
rotate_logs # 发现日志有新写入时触发轮转
fi
通过-a(AND)和-o(OR)构建复杂条件:
bash
if [ -f "/data/$filename" -a -s "/data/$filename" ]; then
process_file "$filename"
fi
性能技巧:将高概率失败的条件放在前面,利用短路逻辑提升效率。
[[ ]]的增强特性双中括号支持模式匹配和类型安全:
bash
if [[ “$file” == *.log && -n $LOGDIR ]]; then
compress_log “$file”
fi
if [[ $count -eq 100 || ${status:-0} -eq 1 ]]; then
handle_error
fi
[ ! -d $DIR ]在DIR含空格时解析错误,改用[[ ! -d "$DIR" ]]解决 set -u暴露未定义变量,避免-z检测失效 $(( ))显式转换:bash
if [ $(( disk_usage + 10 )) -gt 100 ]; then ... 从-a的古老兼容到-z的空值审判,这26个字母构筑了Shell脚本的逻辑脊柱。真正的高手不仅熟记参数表,更深谙何时用[ ]保守兼容,何时用[[ ]]放飞特性。当你能在脚本中精准驾驭-nt(文件新旧比较)这类冷门参数时,便已握住了Shell编程的密钥。