三、条件测试

三、条件测试

为了能够正确处理Shell程序运行过程中遇到的各种情况,Linux Shell提供了一组测试运算符。通过这些运算符,Shell程序能够判断某种或者几个条件是否成立。条件测试在各种流程控制语句,例如判断语句和循环语句中发挥了重要的作用,所以了解和掌握这些条件测试是非常重要的。

在shell程序中,用户使用测试语句来测试指定的条件表达式的条件的真或假。当指定的条件为真时,整个条件测试的返回值为0;反之,如果指定的条件为假,则条件测试语句的返回值为非0值。

3.1条件测试的基本语法

bash 复制代码
格式1: test  -选项  条件表达式
格式2: [  条件表达式  ]     # 注意:[]的左右要有空格   
格式3: [[  条件表达式  ]]   # 注意:[[]]的左右要有空格
格式4: ((条件表达式))

!Note

条件测试的目标可以是文件、字符串、整数;

test,\[\]和\[]语法适用于测试文件、字符串和整数;

(())语法只可以测试整数。

3.2文件测试表达式

常用的文件测试操作符 说明
-a/-e 文件 文件是否存在
-b 文件 文件是否存在,且为块文件,如果文件存在且是一个块文件,则结果为0
-c 文件 文件是否存在且为字符文件,如果文件存在且是一个字符文件,则结果为0
-L 文件 文件存在且为链接文件则为真
-d 文件 文件存在且为目录则为真,即测试表达式成立
-f 文件 文件存在且为普通文件则为真,即测试表达式成立
-s 文件 文件存在且文件大小不为0则为真
-u 文件 文件是否设置suid位,如果设置了suid,则结果为0
-r 文件 文件存在且可读为真
-w 文件 文件存在且可写为真
-x 文件 文件存在且可执行则为真
f1 -nt f2,nt为newer than 文件f1比文件f2新则为真,根据文件的修改时间来计算
f1 -ot f2,ot为older than 文件f1比文件f2旧则为真,根据文件的修改时间来计算
bash 复制代码
[root@server ~]# test -d /root && echo y || echo n
y
[root@server ~]# [ -d /root ] && echo y || echo n
y
[root@server ~]# [[ -d /root ]] && echo y || echo n
y
#如果文件存在,输出文件已经存在,如果不存在则创建
[root@server ~]# [ -e /root/file ] && echo "file alreay exists" || touch /root/file
#因为文件已经创建了,所以再次执行会提示已存在
[root@server ~]# [ -e /root/file ] && echo "file alreay exists" || touch /root/file
file alreay exists

**练习:**让用户输入一个文件名,并做如下判断:

(1)如果用户输入的文件名为空时显示:you must input a filename,并中断程序;

(2)如果用户输入的文件不存在时,显示the file do not exist,并中断程序;

(3)如果文件存在,判断该文件的文件类型和执行者对该文件所拥有的的权限。

说明:由于root在很多权限的限制上面都是无效的,所以使用root执行这个脚本时,常常会发现与ls -l的结果不相同。所以建议使用一般用户来执行这个脚本。

shell 复制代码
[root@server ~]# mkdir /shell/chap03
[root@server ~]# vim /shell/chap03/test1.sh
read -p "input a filename:" filename
test -z $filename && echo "you must input a filename" && exit 0
test ! -e $filename && echo "the file $filename do not exist" && exit 0
test -f $filename && filetype="regulare file"
test -d $filename && filetype="directory"
test -r $filename && perm="readable"
test -w $filename && perm="$perm writable"
test -x $filename && perm="$perm executable"
echo "the $filename is a $filetype"
echo "and the permissons are: $perm"
[root@server ~]# bash /shell/chap03/test1.sh
input a filename:/root
the /root is a directory
and the permissons are: readable writable executable

3.3字符串测试表达式

常用字符串测试操作符 说明
-n "字符串" 若字符串的长度不为0,则为真,即测试表达式成立,n可以理解为no zero
-z "字符串" 若字符串的长度为0,则为真,z可以理解为zero
"串1" = "串2" 若字符串1等于字符串2,则为真,可使用==代替=
"串1" != "串2" 若字符串1不等于字符串2,则为真

建议使用双引号将字符串或者变量引起来,不然可能出现错误的判断结果。

=和!=的判断时,左右两边字符串和符号间需要有空格。

bash 复制代码
[root@server ~]# test -n "abc";echo $?
0
[root@server ~]# test -n "";echo $?
1
[root@server ~]# test -n " ";echo $?
0
[root@server ~]# [ -n " " ];echo $?
0
[root@server ~]# [[ -n " " ]];echo $?
0
[root@server ~]# test "abc" = "abcd" ;echo $?
1
[root@server ~]# test "abc" != "abcd" ;echo $?
0
[root@server ~]# [ "abc" != "abcd" ] ;echo $?
0
#如果测试的对象是变量,变量需要加引号
[root@server ~]# str1="abc"
[root@server ~]# str2="abcd"
[root@server ~]# test "$str1" = "$str2";echo $?
1

3.4整数测试表达式

在\[\]以及test中使用的比较符号 在(())和\[]中使用的比较符号 说明
-eq ==或= 相等,全拼为equal
-ne != 不相等,全拼为not equal
-gt > 大于,全拼为greater than
-ge >= 大于等于,全拼为greater equal
-lt < 小于,全拼为less than
-le <= 小于等于,全拼为less equal
bash 复制代码
[root@server ~]# test 5 -gt 3  && echo y || echo n
[root@server ~]# [ 5 -gt 3 ] && echo y || echo n
y
[root@server ~]# [[ 5 > 3 ]] && echo y || echo n
y
[root@server ~]# (( 5 > 3 )) && echo y || echo n
y

\[]的特殊用法:

使用=~可以判断左侧是否包含右侧表达式中的字符。

bash 复制代码
[root@server ~]# n=123
[root@server ~]# [[ "$n" =~ ^[0-9]+$ ]] && echo y || echo n
y
[root@server ~]# n=123a
[root@server ~]# [[ "$n" =~ ^[0-9]+$ ]] && echo y || echo n
n

3.5逻辑操作符

在\[\]、test中使用的逻辑操作符 \[]和(())中使用的逻辑操作符 说明
-a && and,与,两端都为真,则结果为真
-o || or,或,两端有一个为真,则结果为真
not,非,两端相反,则结果为真
bash 复制代码
[root@server ~]# test -f /etc/passwd -a "abc" = "abcd" ;echo $?
1
[root@server ~]# ! test 3 -eq 3;echo $?
1
[root@server ~]# [ -f /etc/passwd -a "abc" = "abcd" ];echo $?
1
[root@server ~]# ! [ 3 -eq 3 ];echo $?
1

[root@server ~]# [[ -f /etc/passwd && "abc" = "abcd" ]];echo $?
1
[root@server ~]# ! [[ 3 -eq 3 ]];echo $?
1

[root@server ~]# (( 1 > 2 || 3 < 4));echo $?
0
[root@server ~]# ! (( 1 > 2 || 3 < 4));echo $?
1

3.6 案例

1、判断当前登录系统的用户数量,如果超过5个则输出"Too many"

bash 复制代码
[root@server ~]# num=$(who | cut -d " " -f1 | sort -u | wc -l)
[root@server ~]# [ $num -gt 5 ] && echo "Too many" || echo "已登录账户数:$num"
已登录账户数:1

2、如果/var/log/messages文件行数大于30行,则显示提示信息

bash 复制代码
[root@server ~]# line=$(cat  /var/log/messages | wc -l)
[root@server ~]# [ "$line" -gt 30 ] && echo  "好大一个文件" || echo  "还能接受"
好大一个文件

3、查看ssh进程是否在运行:查看进程是否存在和查看是否监听,最后比较的数值不一样。

bash 复制代码
[root@server ~]# num=$(ps -ef | grep ssh | wc -l) 
[root@server ~]# [ "$num" -gt 1 ] && echo "ssh is running" || echo "ssh is not running"
ssh is running
[root@server ~]# num=$(ss -lntup | grep 22| wc -l)
[root@server ~]# [ "$num" -gt 0 ] && echo "ssh is running" || echo "ssh is not running"
ssh is running

4、编写脚本compute.sh,从键盘读入x,y,计算和值后输出

bash 复制代码
[root@server ~]# vim /shell/chap03/compute.sh
#!/bin/bash

read -p "请输入x的值:" x

read -p "请输入y的值:" y

if  [ -n "$x" -a  -n  "$y" ]  # -n判断非空
then
        if  [[ "$x" =~ ^[0-9]+$ ]]  &&  [[ "$y" =~ ^[0-9]+$ ]] # 判断是数字
        then
                echo  $x+$y=$[x+y]
        else
                echo  "请输入数字"
        fi
else
        echo "请输入有效内容"
fi
[root@server ~]# bash /shell/chap03/compute.sh
请输入x的值:3
请输入y的值:4
3+4=7
相关推荐
AlfredZhao1 天前
生产环境里,为什么不建议把普通端口直接暴露到公网?
linux·https·443·80
戴为沐2 天前
Linux内存扩容指南
linux
zylyehuo3 天前
Linux 彻底且安全地删除文件
linux
用户805533698033 天前
主线 U-Boot 上 RK3506:和闭源 rkbin 拔河的三个隐性契约
linux·嵌入式
用户034095297913 天前
linux fcitx 5 雾凇拼音 设置在中文输入法下仍然输入英文标点
linux
乘云数字DATABUFF3 天前
5分钟部署开源APM Databuff:OpenTelemetry全链路追踪入门实战
运维·后端
Web3探索者5 天前
可视化服务器管理和传统命令行区别是什么?新手教程:Linux 运维到底该用图形界面还是 SSH 命令行?
linux·ssh
zylyehuo5 天前
Linux系统中网线与USB网络共享冲突
linux
荣--5 天前
一键部署不是为了省时间 —— 它是把"买来的 PaaS"变成"自己的平台"的拐点
运维·zabbix·工程化·一键部署·平台化·边界设计
江华森5 天前
动手实战学 Docker — 从零到集群编排完全指南
运维