三、条件测试

三、条件测试

为了能够正确处理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
相关推荐
岳来1 小时前
linux 设备目录/dev 学习
linux·服务器·/dev
开开心心就好1 小时前
带可视化界面的目录文件合并工具
java·运维·科技·游戏·tomcat·自动化·powerpoint
爱喝水的鱼丶1 小时前
SAP-ABAP:第二篇:实操避坑篇——ABAP Hello World程序创建、语法校验到调试运行全流程指南
运维·服务器·数据库·学习·sap·abap
xhbh6661 小时前
主机端口映射完全教程:路由器端口转发+云安全组配置+虚拟机NAT转发
服务器·网络·智能路由器·端口映射·映射
wanderist.1 小时前
完美解决VS Code/Cursor远程连接报错:远程主机不满足运行 VS Code 服务器的先决条件(附AI编程最佳实践)
运维·服务器·ssh·ai编程
wanhengidc1 小时前
服务器 科学技术
运维·服务器·安全·web安全
韩明君1 小时前
Debian12安装RabittMQ 4.3.0
linux·debian·高并发·debian12·rabittmq
雨的旋律20991 小时前
keepalived + LVS DR
服务器·网络·lvs
晓翔仔1 小时前
从零搭建自己的网站 AI 助手:阿里云百炼 + 云服务器部署全教程
服务器·人工智能·阿里云·token·ai助手