shell-条件判断

工具教程4个月前发布 hank
330 0 0

基础语法

Shell 条件判断常见有三种写法:[ ][[ ]](( ))。日常写 Bash 脚本时,推荐优先使用 [[ ]];做整数计算或整数比较时,可以使用 (( ))

写法 用途 特点 示例
[ ] 传统 test 判断。 兼容性好,但变量建议加双引号,空变量容易踩坑。 [ -f "$file" ]
[[ ]] Bash 扩展判断。 更适合日常脚本,支持 &&||、通配和正则。 [[ -f "$file" ]]
(( )) 整数计算和整数比较。 写法接近 C 语言,适合数值判断。 (( cpu_usage > 80 ))
#!/bin/bash

file="/etc/fstab"
cpu_usage=85

if [[ -f "$file" ]]; then
    echo "$file 存在"
fi

if (( cpu_usage > 80 )); then
    echo "CPU 使用率过高"
fi

文件与目录判断

文件判断是 Shell 里最常用的一类。记几个高频的就够用:-e 看是否存在,-f 看是否普通文件,-d 看是否目录,-s 看是否非空。

判断 含义 常见用途
-e FILE 文件或目录存在,Exist。 只关心路径是否存在。
-f FILE 存在且为普通文件,File。 判断配置文件、日志文件、脚本文件。
-d FILE 存在且为目录,Directory。 判断目录是否存在。
-s FILE 存在且非空,Size > 0。 判断文件是否有内容。
-r FILE 存在且当前用户可读,Readable。 读取配置前检查权限。
-w FILE 存在且当前用户可写,Writable。 写日志、写配置前检查权限。
-x FILE 存在且当前用户可执行,Executable。 执行脚本或二进制前检查权限。
-L FILE 存在且为软链接,Symbolic Link。 判断路径是否为软链接。
CONFIG_FILE="/etc/fstab"
LOG_FILE="/var/log/messages"
DATA_DIR="/data"

if [[ -f "$CONFIG_FILE" ]]; then
    echo "配置文件存在"
fi

if [[ -d "$DATA_DIR" ]]; then
    echo "目录存在"
fi

if [[ -s "$LOG_FILE" ]]; then
    echo "日志文件存在且非空"
fi

字符串判断

字符串判断常用 -z-n。使用单括号 [ ] 时,变量建议加双引号;使用 [[ ]] 时不加也通常没问题,但保持加双引号更统一。

判断 含义 示例
-z STRING 字符串长度为 0,空字符串。 [[ -z "$name" ]]
-n STRING 字符串长度非 0,非空字符串。 [[ -n "$name" ]]
STRING1 = STRING2 两个字符串相等。 [[ "$a" = "$b" ]]
STRING1 == STRING2 两个字符串相等,Bash 中常用。 [[ "$a" == "$b" ]]
STRING1 != STRING2 两个字符串不相等。 [[ "$a" != "$b" ]]
STRING =~ REGEX 正则匹配,只适用于 [[ ]] [[ "$ip" =~ ^192\.168\. ]]
USER_INPUT=""
ENV_NAME="prod"

if [[ -z "$USER_INPUT" ]]; then
    echo "输入为空,请重新输入。"
fi

if [[ "$ENV_NAME" == "prod" ]]; then
    echo "当前是生产环境"
fi

if [[ "$ENV_NAME" != "test" ]]; then
    echo "当前不是测试环境"
fi

整数比较

整数比较可以用 -eq 这一套,也可以用 (( ))。如果只写 Bash 脚本,(( )) 更直观;如果已经在 [[ ]] 里,也可以继续用 -gt-lt 这些。

判断 含义 对应符号
-eq 等于,Equal。 ==
-ne 不等于,Not Equal。 !=
-gt 大于,Greater Than。 >
-ge 大于等于,Greater than or Equal。 >=
-lt 小于,Less Than。 <
-le 小于等于,Less than or Equal。 <=
CPU_USAGE=85
DISK_USAGE=92

# 写法 1:[[ ]] + -gt
if [[ "$CPU_USAGE" -gt 80 ]]; then
    echo "告警:CPU 负载过高 ($CPU_USAGE%)"
fi

# 写法 2:(( )),更适合整数比较
if (( DISK_USAGE >= 90 )); then
    echo "告警:磁盘使用率过高 ($DISK_USAGE%)"
fi

注意:-eq-gt 这些只适合整数。字符串比较不要写 [[ "$a" -eq "$b" ]],应该用 [[ "$a" == "$b" ]]

逻辑组合

多个条件可以组合使用。使用 [[ ]] 时,可以直接写 &&||;使用传统 [ ] 时,更推荐拆成多个判断。

file="/etc/fstab"
dir="/data"
user="root"

# 文件存在且可读
if [[ -f "$file" && -r "$file" ]]; then
    echo "$file 存在且可读"
fi

# 目录不存在则创建
if [[ ! -d "$dir" ]]; then
    mkdir -p "$dir"
fi

# 用户是 root 或 admin
if [[ "$user" == "root" || "$user" == "admin" ]]; then
    echo "管理员用户"
fi

传统 [ ] 写法

file="/etc/fstab"

if [ -f "$file" ] && [ -r "$file" ]; then
    echo "$file 存在且可读"
fi

常用示例

1. 判断配置文件是否存在

#!/bin/bash

CONFIG_FILE="/etc/fstab"

if [[ -f "$CONFIG_FILE" ]]; then
    echo "配置文件 $CONFIG_FILE 存在,准备读取。"
else
    echo "错误:找不到配置文件!"
    exit 1
fi

2. 判断目录,不存在就创建

DATA_DIR="/data/app"

if [[ ! -d "$DATA_DIR" ]]; then
    mkdir -p "$DATA_DIR"
fi

3. 判断命令是否存在

检测系统里有没有某个命令时,优先用 command -v

if command -v tcpdump >/dev/null 2>&1; then
    echo "tcpdump 已安装"
else
    echo "tcpdump 未安装"
fi

4. 判断脚本参数是否为空

#!/bin/bash

if [[ -z "$1" ]]; then
    echo "用法:$0 文件路径"
    exit 1
fi

target="$1"

if [[ -e "$target" ]]; then
    echo "$target 存在"
else
    echo "$target 不存在"
fi

5. 判断服务端口是否监听

这类判断通常结合命令退出状态,不一定非要用文件或字符串判断。

PORT=80

if ss -tln | grep -q ":$PORT "; then
    echo "端口 $PORT 正在监听"
else
    echo "端口 $PORT 未监听"
fi

常见坑

问题 错误示例 推荐写法
[ 两边必须有空格。 [$a = 1] [ "$a" = "1" ]
单括号里变量建议加双引号。 [ $name = root ] [ "$name" = "root" ]
字符串比较不要用整数比较符。 [[ "$name" -eq "root" ]] [[ "$name" == "root" ]]
整数比较不要用字符串大小比较。 [[ "$num" > 10 ]] (( num > 10 ))
[[ ]] 的通配匹配和引号有关。 [[ "$file" == "*.log" ]] [[ "$file" == *.log ]]

速记:文件判断看横杠:-f 文件、-d 目录、-e 存在;字符串判断看长度:-z 为空、-n 非空;整数判断看英文缩写:eq 等于、gt 大于、lt 小于。

注:日常 Bash 脚本里,条件判断优先用 [[ ]];整数计算和整数比较优先用 (( ))

© 版权声明

相关文章