三、条件测试

三、条件测试

为了能够正确处理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
相关推荐
讯捷蓝达22 分钟前
戴尔R720xd服务器卡死在 “Configuring Memory...Done“,换了内存还是卡?问题根本不在内存
运维·服务器
且从容.1 小时前
ubuntu安装flink
linux·ubuntu·flink
数字新视界3 小时前
动环监控信创适配在智能机房管理中的应用价值与未来展望
大数据·服务器·数据库·动环监控系统·动力与环境监控系统
爱和冰阔落3 小时前
【Linux网络】TCP 服务器如何并发处理多个客户端?从 fork、僵尸进程到双重 fork
linux·运维·服务器·网络
程序员沉梦听雨3 小时前
WSL2的安装与使用
linux·wsl
微小的鱼3 小时前
Linux的渲染与显示系统链路
android·java·linux
lisanmengmeng3 小时前
alertmanger 标签 rules 打上分组标签
linux·运维·服务器
Android系统攻城狮4 小时前
Linux FFmpeg深度解析之av_write_frame调用流程与实战(三十三)
linux·运维·服务器·ffmpeg·音视频进阶·ffmpeg音视频
上火的金鱼妹4 小时前
k8s生产实际问题排查(网关,数据库读写等)
运维·服务器
孙克旭_4 小时前
k8s基础组件与创建资源
运维·docker·容器·kubernetes