条件测试常用语法
在 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