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
相关推荐
齐潇宇2 小时前
Tomcat服务
linux·运维·网络·http·tomcat·web应用
木下~learning2 小时前
嵌入式Linux 小项目:RK3399 基于 MPlayer 实现视频播放器(从环境搭建到完整播放列表)
linux·运维·嵌入式硬件·音视频
DO your like2 小时前
Vim编辑器指令
linux·编辑器·vim
web前端神器2 小时前
宝塔服务器网址ERR_CONNECTION_REFUSED报错排查流程
java·linux·服务器
davidson14712 小时前
Ubuntu配置Claude
linux·人工智能·ubuntu·claude
书到用时方恨少!2 小时前
Vi/Vim 文本编辑器使用指南:指尖上的魔法
linux·编辑器·vim
念恒123063 小时前
Linux基础开发工具(Vim篇)
linux·c语言
有味道的男人3 小时前
抖音关键词搜索,视频详情api
linux·数据库·音视频
念恒123063 小时前
Linux基础开发工具(yum篇)
linux·c语言