基础语法
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 脚本里,条件判断优先用 [[ ]];整数计算和整数比较优先用 (( ))。
© 版权声明
文章版权归作者所有,未经允许请勿转载。