四川交投建设工程股份有限公司网站,塘沽网吧开门了吗,waP六感程序建设网站,做网站页面的视频第三章 Shell条件测试
用途 为了能够正确处理Shell程序运行过程中遇到的各种情况#xff0c;Linux Shell提供了一组测试运算符。 通过这些运算符#xff0c;Shell程序能够判断某种或者几个条件是否成立。 条件测试在各种流程控制语句#xff0c;例如判断语句和循环语句中…第三章 Shell条件测试
用途 为了能够正确处理Shell程序运行过程中遇到的各种情况Linux Shell提供了一组测试运算符。 通过这些运算符Shell程序能够判断某种或者几个条件是否成立。 条件测试在各种流程控制语句例如判断语句和循环语句中发挥了重要的作用所以了解和掌握这些条件测试是非常重要的
基本语法
格式 格式1 test -参数 条件表达式test 数值比较 -eq test a -eq b test 字符比较 a b test a b [ ] 算数比较 -eq 但 运算符有问题需要通过\转义符 -a -o ! [ ] 字符比较test支持 不支持-eq 测试符和测试值之间通过空格分割[[ ]] || 算数比较不需要转义符 [[ ]] 可以支持正则 ~格式2 [ 条件表达式 ] # 注意[]的左右要有空格
格式3 [[ 条件表达式 ]] # 注意[]的左右要有空格
格式4 ((条件表达式))
重点数值比较符通过字符类的测试测试
test[ ][[ ]] ---支持正则符数值比较test 1-eq 2 (-eq -gt -lt -ge -le -ne)-eq -gt -lt -ge -le -ne -a -o -eq -gt -lt -ge -le -ne || --测试符都支持字符比较test a b 或者 test a b -a -o ! -a -o ! || ! a ~ .* a a test单独使用判断条件为真echo $?返回0假返回1 test与[ ]等价 [[ ]] 是扩展命令可以使用通配符等进行模式匹配 || 等操作符可以直接应用于双中括号中但不能用于单中括号中 (()) 一般用于if语句里两端不需要有空格测试对象为整数
例
# test语法
[rootserver ~]# test -f /etc/passwd
[rootserver ~]# echo $?
0
[rootserver ~]# test -f /etc/aa
[rootserver ~]# echo $?
1
[rootserver ~]#
[rootserver ~]# test -f /etc/passwd echo 1 || echo 0
1
[rootserver ~]# test -f /etc/aa echo 1 || echo 0
0
[rootserver ~]# test -f /etc/passwd echo yes || echo no
yes
[rootserver ~]# test -f /etc/aa echo yes || echo no
no
[rootserver ~]# if test -f /etc/passwd ; then echo 1 ; else echo no ;fi
1
[rootserver ~]# if test -f /etc/aa ; then echo 1 ; else echo no ;fi
no
# [] 语法
[rootserver ~]# [-f /etc/passwd] # 注意[] 中要有空格
bash: [-f: command not found...
[rootserver ~]# [ -f /etc/passwd ]
[rootserver ~]# echo $?
0
[rootserver ~]# [ -f /etc/aa ]
[rootserver ~]# echo $?
1
[rootserver ~]# [ -f /etc/aa ] echo y || echo n
n
[rootserver ~]# [ -f /etc/passwd ] echo y || echo n
y
[rootserver ~]# if [ -f /etc/passwd ] ; then echo 1 ; else echo no ;fi
1
[rootserver ~]# if [ -f /etc/aa ] ; then echo 1 ; else echo no ;fi
no
# [[]] 语法
[rootserver ~]# [[ 3 2 || 1 2 ]] echo 1 || echo 0
1
[rootserver ~]# [[ 3 2 1 2 ]] echo 1 || echo 0
0
(()) 语法
[rootserver ~]# ((95)) echo 1 || echo 0
1
[rootserver ~]# (( 9 5 )) echo 1 || echo 0
1
[rootserver ~]# ((95)) echo 1 || echo 0
1
[rootserver ~]# ((913)) echo 1 || echo 0
0
[rootserver ~]# ((913.5)) echo 1 || echo 0 # 注意不支持小数运算
-bash: ((: 913.5语法错误: 无效的算术运算符 (错误符号是 .5)
0
文件测试
参数
参数作用-b 文件名检测文件是否是块设备文件是返回 true-c 文件名是否是字符设备文件-d 文件名是否是目录-f 文件名是否是普通文件既不是目录也不是设备文件-S 文件名是否为socket文件-P 文件名是否为管道符文件-L 文件名是否为链接文件-u 文件名是否有suid的权限-s 文件名是否为空文件大小是否大于0不为空返回 true-e 文件名检测文件包括目录是否存在如果是则返回 true-r 文件名检测文件是否可读如果是则返回 true。-w 文件名检测文件是否可写如果是则返回 true-x 文件名检测文件是否可执行如果是则返回 truef1 -nt f2文件f1比文件f2新则为真根据文件修改时间计算f1 -ot f2文件f1比文件f2旧则为真根据文件修改时间计算
例
//普通文件测试
[rootlocalhost ~]# touch file1.txt
[rootlocalhost ~]# [ -f file1.txt ] echo yes || echo no
yes
//目录测试
[rootlocalhost ~]# [ -d /tmp ] echo yes || echo no
yes
//测试文件属性
[rootlocalhost ~]# ll file1.txt
-rw-r--r-- 1 root root 0 8月 28 12:30 file1.txt
[rootlocalhost ~]# [ -r file1.txt ] echo yes || echo no
yes
[rootlocalhost ~]# [ -x file1.txt ] echo yes || echo no
no
[ -e ]
[ -s ]
[rootserver ~]# [ -d /root ] echo y || echo n
y
[rootserver ~]# [ -d /aa ] echo y || echo n
n
[rootserver ~]# [ -b /dev/nvme0n1 ] echo y || echo n
y
[rootserver ~]# [ -L /dev/cdrom ] echo y || echo n
y
[rootserver ~]# ll /dev/cdrom
lrwxrwxrwx 1 root root 3 3月 22 11:31 /dev/cdrom - sr0
[rootserver ~]# [ -e /file1 ] echo y || echo n
n
[rootserver ~]# touch /file1
[rootserver ~]# [ -e /file1 ] echo y || echo n
y
# 编写脚本测试文件是否存在不存在则创建
[rootserver ~]# vim temp1.sh
#!/bin/bash
FILE$1
echo FILE
if test -e $FILE
thenecho $FILE文件已存在
else echo $FILE文件不存在开始新建...touch $FILEls -l $FILE
fi
[rootserver ~]# bash temp1.sh /etc/passwd
/etc/passwd
/etc/passwd文件已存在
[rootserver ~]# bash temp1.sh temp
temp
temp文件不存在开始新建...
-rw-r--r-- 1 root root 0 6月 17 14:53 temp
# 上例改写
[rootserver ~]# vim temp1.sh
#!/bin/bash
read -p 请输入文件名: FILE
if test -e $FILE
thenecho $FILE文件已存在
elseecho $FILE文件不存在开始新建...touch $FILEls -l $FILE
fi
[rootserver ~]# bash temp1.sh
请输入文件名: /etc/sos/sos.conf
/etc/sos/sos.conf文件已存在
[rootserver ~]# bash temp1.sh
请输入文件名: t1
t1文件不存在开始新建...
-rw-r--r-- 1 root root 0 6月 17 14:56 t1 字符串运算符
示例 //-n如果字符串长度不为零输出yes否则输出no
[rootlocalhost ~]# [ -n hello ] echo yes || echo no
yes
[rootlocalhost ~]# [ -n ] echo yes || echo no
no
注意//变量为空时通过[[]]进行测试[]测试有问题
[rootlocalhost ~]# strgrep xixi /etc/passwd
[rootlocalhost ~]# [[ -n $str ]] echo 有 || echo 无
无
[rootlocalhost ~]# [ -n $str ] echo 有 || echo 无
有//-z如果字符串长度为零输出yes否则输出no
[rootlocalhost ~]# [ -z hello ] echo yes || echo no
no
[rootlocalhost ~]# [ -z ] echo yes || echo n
yes
// 字符串相等比较
注意的左右有空格没有空格将会导致逻辑错误。
[rootlocalhost ~]# [ HELLO hello ] echo yes || echo no
no
[rootlocalhost ~]# [ HELO ! hello ] echo yes || echo no
yesif [ -z $a ]
thenecho -z $a : 字符串长度为 0
elseecho -z $a : 字符串长度不为 0
fi
if [ -n $a ]
thenecho -n $a : 字符串长度不为 0
elseecho -n $a : 字符串长度为 0
fi
if [ $a ] -------$判断z字符串是否为空不空为真空为假
thenecho $a : 字符串不为空
elseecho $a : 字符串为空
fi 整数测试(关系运算符 )
作用 用于比较两个数值的大小关系操作的对象是数值
操作符 数值测试
[root172 ~]# [ 1 -eq 2 ] echo yes || echo no
no
[root172 ~]# test 1 -eq 2 echo yes || echo no
no
[root172 ~]# [[ 1 2 ]] echo yes || echo no
no
[root172 ~]# [[ 1 -eq 2 ]] echo yes || echo no
no
[root172 ~]# ((12)) echo yes || echo no
no字符串比较
[root172 ~]# [[ a b ]]
[root172 ~]# echo $?
1
示例
[rootlocalhost ~]# [ 5 -gt 3 ] echo yes || echo no
yes
[rootlocalhost ~]# [ id -u -eq 0 ] echo admin || echo other
admin
[rootlocalhost ~]# su - student
[studentlocalhost ~]$ [ id -u -eq 0 ] echo admin || echo other
other 例
[rootserver ~]# [ 5 -gt 3 ] echo y || echo n
y
[rootserver ~]# test 5 -gt 3 echo y || echo n
y
[rootserver ~]# ((53)) echo y || echo 0
y
# 知识拓展
# 检查左侧内容是否包含右侧的表达式可以使用 ~ 正则匹配表示是否包含
[rootserver ~]# n123
[rootserver ~]# [[ $n ~ ^[0-9]$ ]] echo y || echo n
y
[rootserver ~]# n123ttt
[rootserver ~]# [[ $n ~ ^[0-9]$ ]] echo y || echo n
n 逻辑操作符/布尔运算符
符号 例
[rootserver ~]# [ -f /etc/passwd -a -f /etc/services ] echo 1 || echo 0
1
[rootserver ~]# [ -f /etc/hosts -o -d /etc/services ] echo 1 || echo 0
1
[rootserver ~]# ((510 52)) echo y || echo n
y
[rootserver ~]# ((2510)) echo y || echo n
y
[rootserver ~]# ((251)) echo y || echo n
n
[rootserver ~]# ((6510)) echo y || echo n
y
[rootserver ~]# ((25-1)) echo y || echo n
n 命令分隔符
cmd1;cmd2 以独立的进程依次执行cmd1和cmd2
(cmd1;cmd2) 在同一进程中依次执行cmd1和cmd2
cmd1cmd2 cmd1和cmd2同时执行分属于不同的进程
cmd1cmd2 当cmd1为真时则执行cmd2
cmd1||cmd2 当cmd1不为真时则执行cmd2
cmd 后台执行
# 若账户fox10不存在则添加账户
[rootserver ~]# id fox10 /dev/null echo fox10已存在 || useradd fox10# /dev/null 表示将左侧命令执行的正确和错误输出到“黑洞”即不显示到屏幕 命令执行顺序 复合指令即一串命令 ()和{}都是对一串的命令进行执行,但有所区别 相同点
()和{}都是把一串的命令放在括号里面,如果命令在一行命令之间用;号隔开()和{}中括号里面的某个命令的重定向只影响该命令,但括号外的重定向则影响到括号里的所有命令
不同点
()只是对一串命令重新开一个子shell进行执行, {}对一串命令在当前shell执行()最后一个命令可以不用分号,{}最后一个命令要用分号()里的第一个命令和左边括号不必有空格,{}的第一个命令和左括号之间必须要有一个空格
示例
[rootlocalhost scripts]# (pwd;cd /tmp;pwd)
/scripts
/tmp
# 子shell中执行执行完毕当前路径不变
[rootlocalhost tmp]# { pwd;cd /tmp;pwd; } aaa
/tmp
/tmp
[rootlocalhost tmp]# pwd;cd /;pwd 示例
// 如果目录/abc存在给出提示信息目录已存在否则创建目录
[ -e /abc -a -d /abc ]
方法1[rootlocalhost ~]# [ -d /abc ] echo exists || mkdir /abc
方法2[rootlocalhost ~]# [ ! -d /abc ] mkdir /abc || echo exists 案例分析 例1判断当前已登录账户数若超过5个则输出“Too many” 分析1)如何查看当前登录用户-- who 2)已登录的用户数-- who | wc -l num$(who | wc -l) [ $num -gt 5 ] echo Too many [rootserver ~]# num$(who | cut -d -f1 | sort -u | wc -l)[rootserver ~]# [ $num -gt 5 ] echo Too many || echo 已登录账户数:$num
已登录账户数:1# who : 查看当前已登录的账户信息# cut -d -f1 以空格为列向分割符截取第1部分# sort -u 去重后排序# wc -l计算行数# 上例改写为
[rootserver ~]# (($num5)) echo Too many || echo 已登录账户数:$num 例2编写脚本temp2.sh 程序从键盘读入一个目录名判断该命令是否存在若不存在则创建并显示目录信息
[rootserver ~]# vim temp2.sh
#!/bin/bashcd /
ls
read -p 请输入一个目录名 dir
test -d $dir ls -l $dir || (echo 目录不存在开始新建... ; mkdir $dir ; ls -l $dir) 例3如果/var/log/messages文件行数大于30行则显示提示信息
[rootserver ~]# (($(cat /var/log/messages | wc -l)30)) echo 好大一个文件 || echo 还能接受 例4编写脚本temp3.sh功能显示root目录下的文件信息之后建立一个aa目录在aa目录下新建一个文件bb.txt并修改该文件的权限为可执行,最后再次浏览信息
[rootserver ~]# vim temp3.sh
#!/bin/bashls -l /rootmkdir /root/aatouch /root/aa/bb.txtchmod x /root/aa/bb.txtls -l /root 例5编写脚本temp4.sh从键盘读入xy计算和值后输出
[rootserver ~]# vim temp4.sh
#!/bin/bashread -p 请输入x的值 xread -p 请输入y的值 yif [ -n $x -a -n $y ] # -n判断非空
thenif [[ $x ~ ^[0-9]$ ]] [[ $y ~ ^[0-9]$ ]] # 判断是数字thenecho $[xy]elseecho 请输入数字fi
elseecho 请输入有效内容
fi 例6编写temp5.sh脚本显示所有用户选择一个用户输入判断是root账户还是系统账户还是普通账户
[rootserver ~]# vim temp5.sh
#!/bin/bashcat /etc/passwd | cut -d : -f1 | sort -uread -p 请输入一个账户名 usus_num$(id -u $us)if (($us_num0))
thenecho 此用户为管理员账户
elseif (($us_num1 $us_num999))thenecho 此账户为系统账户elseecho 普通账户fi
fi 例7编写脚本temp6.sh 给定文件/etc/sos/sos.conf判断是否存在空白行若存在则显示行数否则显示“无空白行”提示信息
[rootserver ~]# vim temp6.sh
#!/bin/bashnum$(grep ^$ /etc/sos/sos.conf | wc -l)if (($num0))
thenecho /etc/sos/sos.conf文件含有空白行,行数$num,位置如下:grep -n ^$ /etc/sos/sos.conf
elseecho /etc/sos/sos.conf此文件无空白行
fi 总结
文件测试算数运算符字符串运算符 -n关系型运算符逻辑运算符