20260413 条件测试常用语法

条件测试常用语法

在 bash 编程里,条件测试常用的语法如下:

  • 语法1:test <判断表达式>,test命令和"<判断表达式>"之间至少有一个空格。
  • 语法2:[ <判断表达式> ],和test命令的用法相同,这是推荐方法。[]的边界和内容之间至少有一个空格。
  • 语法3:[[ <判断表达式> ]],是比test和[]更新的语法格式。[[]]的边界和内容之间至少有一个空格。
  • 语法4:(( <判断表达式> )),一般用于 if 语句。(())(双小括号)两端不需要有空格。
  • 语法5:comand,命令的返回值确定表达式的真值或假值。

条件测试常用于判断以下内容:

  • 字符串
  • 数值
  • 文件、进程、服务、用户等

一、test

bash 复制代码
[root@centos7 ~ 09:29:23]# man test
test: test [expr]
    Evaluate conditional expression.

    Exits with a status of 0 (true) or 1 (false) depending on
    the evaluation of EXPR.  Expressions may be unary or binary.  Unary
    expressions are often used to examine the status of a file.  There
    are string operators and numeric comparison operators as well.

    The behavior of test depends on the number of arguments.  Read the
    bash manual page for the complete specification.

    File operators:

      -a FILE        True if file exists.
      -b FILE        True if file is block special.
      -c FILE        True if file is character special.
      -d FILE        True if file is a directory.
      -e FILE        True if file exists.
      -f FILE        True if file exists and is a regular file.
      -g FILE        True if file is set-group-id.
      -h FILE        True if file is a symbolic link.
      -L FILE        True if file is a symbolic link.
      -k FILE        True if file has its `sticky' bit set.
      -p FILE        True if file is a named pipe.
      -r FILE        True if file is readable by you.
      -s FILE        True if file exists and is not empty.
      -S FILE        True if file is a socket.
      -t FD          True if FD is opened on a terminal.
      -u FILE        True if the file is set-user-id.
      -w FILE        True if the file is writable by you.
      -x FILE        True if the file is executable by you.
      -O FILE        True if the file is effectively owned by you.
      -G FILE        True if the file is effectively owned by your group.
      -N FILE        True if the file has been modified since it was last read.

      FILE1 -nt FILE2  True if file1 is newer than file2 (according to
                       modification date).

      FILE1 -ot FILE2  True if file1 is older than file2.

      FILE1 -ef FILE2  True if file1 is a hard link to file2.

    String operators:

      -z STRING      True if string is empty.

      -n STRING
         STRING      True if string is not empty.

      STRING1 = STRING2
                     True if the strings are equal.
      STRING1 != STRING2
                     True if the strings are not equal.
      STRING1 < STRING2
                     True if STRING1 sorts before STRING2 lexicographically.
      STRING1 > STRING2
                     True if STRING1 sorts after STRING2 lexicographically.

    Other operators:

      -o OPTION      True if the shell option OPTION is enabled.
      -v VAR     True if the shell variable VAR is set
      ! EXPR         True if expr is false.
      EXPR1 -a EXPR2 True if both expr1 AND expr2 are true.
      EXPR1 -o EXPR2 True if either expr1 OR expr2 is true.

      arg1 OP arg2   Arithmetic tests.  OP is one of -eq, -ne,
                     -lt, -le, -gt, or -ge.

    Arithmetic binary operators return true if ARG1 is equal, not-equal,
    less-than, less-than-or-equal, greater-than, or greater-than-or-equal
    than ARG2.

    Exit Status:
    Returns success if EXPR evaluates to true; fails if EXPR evaluates to
    false or an invalid argument is given.

1. 判断文件

判断文件是否存在

bash 复制代码
[root@centos7 ~ 10:40:25]# su - jqz
Last login: Mon Apr 13 10:39:37 CST 2026 on pts/0
-bash: /etc/bashrc: Permission denied
[jqz@centos7 ~ 10:40:30]$ file=/etc/fstab
# 如果文件存在,则显示文件存在
[jqz@centos7 ~ 10:40:37]$ test -a $file && echo "$file is exist." || echo "$file is not exist."
# 输出内容如下
/etc/fstab is exist.

[jqz@centos7 ~ 10:40:42]$ file=/etc/fstab-abc
# 如果文件不存在,则显示文件不存在
[jqz@centos7 ~ 10:40:50]$ test -a $file && echo "$file is exist." || echo "$file is not exist."
# 输出内容如下
/etc/fstab-abc is not exist.

2. 判断目录是否存在:

  • 如果不存在,则创建目录。
  • 如果存在,则提示目录存在。
bash 复制代码
[jqz@centos7 ~ 10:44:00]$ dir_path=/home/jiang/webapp
[jqz@centos7 ~ 10:44:18]$ ls ${dir_path} 
ls: cannot access /home/jiang/webapp: No such file or directory

# 执行完成后,创建了目录
[jqz@centos7 ~ 10:44:26]$ test -d ${dir_path} && echo "${dir_path} is exist." || mkdir  ${dir_path}
[jqz@centos7 ~ 10:44:29]$ ls -d ${dir_path}
/home/jiang/webapp

# 提示目录已经存在
[jqz@centos7 ~ 10:49:42]$ test -d ${dir_path} && echo "${dir_path} is exist." || mkdir  ${dir_path}
/home/jiang/webapp is exist.

3. 其他示例

bash 复制代码
# 如果对文件具有读取权限,则显示文件内容
[jqz@centos7 ~ 10:49:50]$ ls -ld /etc/fstab /etc/shadow
-rw-r--r--. 1 root root 541 Apr  3 14:10 /etc/fstab
----------  1 root root 688 Apr 13 10:37 /etc/shadow

# 无读取权限,输出内容为空
[jqz@centos7 ~ 10:51:34]$ test -r /etc/fstab && tail -5 /etc/fstab 
#
/dev/mapper/centos-root /                       xfs     defaults        0 0
UUID=1906c7bf-f40a-49f9-bbd8-b9c65572a8ea /boot                   xfs     defaults        0 0
/dev/mapper/centos-home /home                   xfs     defaults        0 0
/dev/mapper/centos-swap swap                    swap    defaults        0 0

思考:对于文件/tmp/test.log,如果有写入权限,则写入"hello world."

bash 复制代码
[jqz@centos7 ~ 10:52:10]$ touch /tmp/test.log 
[jqz@centos7 ~ 10:52:48]$ test -w /tmp/test.log && echo "hello world." > /tmp/test.log 
[jqz@centos7 ~ 10:53:37]$ cat /tmp/test.log 
hello world.

4. 判断字符串

  • -z STRING,字符串为空,则为true
  • -n STRING,字符串非空,则为true
bash 复制代码
# 测试变量是否定义
[jqz@centos7 ~ 10:53:43]$ test -z "$testvar" && echo 'testvar is not defined.' || echo "testvar is $testvar."
testvar is not defined.

[jqz@centos7 ~ 10:55:05]$ testvar=hi
[jqz@centos7 ~ 10:55:18]$ test -z "$testvar" && echo 'testvar is not defined.' || echo "testvar is $testvar."
# 输出变量值
testvar is hi.

# 取消变量定义
[jqz@centos7 ~ 10:57:20]$ test -n "testvar" && echo "test is $ testvar." || \ testvar=zhangsan
test is $ testvar.
  • STRING1 = STRING2,True if the strings are equal.
  • STRING1 != STRING2,True if the strings are not equal.
bash 复制代码
# 检查当前运行的用户
# 如果不是root用户,则提示:请以root身份运行
# 如果是root用户,则执行创建用户zhangsan

# 普通用户运行,则提示:请以root身份运行
[root@centos7 ~ 10:34:05]# test "$UESR" = "root" && useradd zhangsan || echo "please run as root."
please run as root.

# root用户运行,创建用户成功
[root@centos7 ~ 10:34:37]# test "$USER" = "root" && useradd zhangsan || echo "Please run as root."
[root@centos7 ~ 10:34:48]# id zhangsan
uid=1001(zhangsan) gid=1001(zhangsan) groups=1001(zhangsan)

# 等效于以下命令
[root@centos7 ~ 11:01:08]# test "$USER" != "root" && echo "Please run as root." || useradd zhangsan
useradd: user 'zhangsan' already exists

5. 判断数值

arg1 OP arg2 Arithmetic tests. OP is one of -eq, -ne, -lt, -le, -gt, or -ge.

bash 复制代码
# 检查当前运行的用户
# 如果不是root用户,则提示:请以root身份运行
# 如果是root用户,则执行删除用户zhangsan

# 普通用户运行,则提示:请以root身份运行
[jqz@centos7 ~ 10:58:01]$ test $UID -eq 0 && useradd -r zhangsan || echo "plaese as root." 
plaese as root.
[jqz@centos7 ~ 11:04:44]$ test $UID -eq 0 && useradd -r zhangsan || echo "please run as root."
please run as root.
[jqz@centos7 ~ 11:05:47]$ id zhangsan
uid=1001(zhangsan) gid=1001(zhangsan) groups=1001(zhangsan)

6. 多条件测试

  • ! EXPR True if expr is false.
  • EXPR1 -a EXPR2 True if both expr1 AND expr2 are true.
  • EXPR1 -o EXPR2 True if either expr1 OR expr2 is true.
bash 复制代码
[root@centos7 ~ 11:01:11]# file=/tmp/test.log 

# 逻辑非:提交取反满足
[root@centos7 ~ 11:21:41]# test ! -a $file && touch $file && echo "create file success."
create file success.
[root@centos7 ~ 11:07:11]# ls $file
/tmp/test.log

# 逻辑与:两个条件同时满足
[root@centos7 ~ 11:11:02]# test -w $file -a -a $file && date > $file
[root@centos7 ~ 11:11:05]# cat $file
Mon Apr 13 11:11:05 CST 2026

# 逻辑或:两个条件任一满足
[root@centos7 ~ 11:22:49]# file1=/etc/yum.conf
[root@centos7 ~ 11:22:54]# file2=/etc/yum.repos.d/CentOS-Base.repo
[root@centos7 ~ 11:22:59]# test -a $file1 -o -a $file2 && echo 'yum repository is exist.'
yum repository is exist.

二、[[ ]]

大部分等效于 [],多条件判断有些区别。

  • ! EXPR True if expr is false.
  • EXPR1 && EXPR2 True if both expr1 AND expr2 are true.
  • EXPR1 || EXPR2 True if either expr1 OR expr2 is true.
bash 复制代码
[jqz@centos7 ~ 11:05:55]$ file=/tmp/test.log 

# 逻辑非:提交取反满足
[jqz@centos7 ~ 11:40:02]$ [[ ! -a $file ]] && touch $file && echo "create file success."
[jqz@centos7 ~ 11:40:25]$ ls $file
/tmp/test.log


# 逻辑与:两个条件同时满足
[jqz@centos7 ~ 11:40:29]$ [[ -w $file && -a $file ]] && date > $file
[jqz@centos7 ~ 11:40:59]$ cat $file
Mon Apr 13 11:40:59 CST 2026

# 逻辑或:两个条件任一满足
[jqz@centos7 ~ 11:41:05]$ file1=/etc/yum.conf 
[jqz@centos7 ~ 11:41:20]$ file2=/etc/yum.repos.d/CentOS-Base.repo 
[jqz@centos7 ~ 11:41:44]$ [[ -a $file1 || -a $file2 ]] && echo 'yum repository is exist.'
yum repository is exist.

3、(())

主要用于数值比较。

bash 复制代码
# 检查当前运行的用户
# 如果不是root用户,则提示:请以root身份运行
# 如果是root用户,则执行删除用户zhangsan

# 普通用户运行,则提示:请以root身份运行
[jqz@centos7 ~ 11:42:44]$ (($UID == 0)) && userdel -r zhangsan || echo "please run as root"
please run as root

# root用户运行,删除用户成功
[root@centos7 ~ 11:23:09]# (($UID == 0)) && userdel -r zhangsan || echo "Please run as root."
[root@centos7 ~ 11:43:55]# id zhangsan
id: zhangsan: no such user
相关推荐
二哈赛车手5 小时前
新人笔记---ES和kibana启动问题以及一些常用的linux的错误排查方法,以及ES,数据库泄密解决方案[超详细]
java·linux·数据库·spring boot·笔记·elasticsearch
嵌入式×边缘AI:打怪升级日志5 小时前
嵌入式Linux开发核心自测题(全系列精华浓缩)
java·linux·运维
嵌入式×边缘AI:打怪升级日志5 小时前
TinaSDK Linux Kernel 基本使用(全志T113开发板)
linux·运维·服务器
嵌入式×边缘AI:打怪升级日志6 小时前
Linux内核基础完全入门指南(理论篇)
linux·运维·服务器
Muyuan19986 小时前
28.Paper RAG Agent 开发记录:修复 LLM Rerank 的解析、Fallback 与可验证性
linux·人工智能·windows·python·django·fastapi
比昨天多敲两行6 小时前
Linux进程概念
linux·运维·服务器
HLC++6 小时前
Linux的基本指令+权限+基础开发工具
linux·运维·服务器
一拳一个娘娘腔6 小时前
红队与蓝队视角:现代网络安全攻防中的Linux命令深度解析
linux·安全
杨云龙UP8 小时前
ODA运维实战:Oracle 19c YJXT PDB表空间在线扩容全过程_20260503
linux·运维·服务器·数据库·oracle
郝学胜-神的一滴8 小时前
跨平台动态库与头文件:从原理到命名的深度解析
linux·c++·程序人生·unix·cmake