shell编程:条件测试与比较(六)
条件测试方法综述


test条件测试的简单语法及测试

范例6-1 测试文件(在test命令中使用-f选项:文件存在且为不同文件则表达式成立)
[root@adminset ~]# test -f file && echo true || echo false
false
[root@adminset ~]# touch file
[root@adminset ~]# test -f file && echo true || echo false
true
范例6-2 测试字符串(在test命令中使用-z选项(如果测试字符串的长度为0,则表达式成立)
[root@adminset ~]# test -z "luoahong" && ehco 1 || echo 0
0
[root@adminset ~]# char="luoahong"
0
[root@adminset ~]# test -z "$char" && echo 1 || echo 0
0
[root@adminset ~]# char=""
[root@adminset ~]# test -z "$char" && echo 1 || echo 0
1
结论:test命令测试的功能很强大,但是和[] [[]]的功能有所重合,因此,在实际工作中选择一种适合自己的语法就好了,对于其他的语法,能读懂别人写的脚本就可以了
[](中括号)条件测试语法及示例
范例6-3 测试文件(利用[]加-f 选项 文件存在且为普通文件则表达式成立)
[root@adminset ~]# [ -f /tmp/luoahong.txt ] && echo 1 ||echo 0
0
[root@adminset ~]# touch /tmp/luoahong.txt
[root@adminset ~]# [ -f /tmp/luoahong.txt ] && echo 1 ||echo 0
1
[root@adminset ~]# [ -f /tmp/luoahong.txt ] ||echo 0
[root@adminset ~]# [ -f /tmp/luoahong1.txt ] ||echo 0
0
[root@adminset ~]# [ -f /tmp/luoahong1.txt ] ||echo 0
0
[root@adminset ~]# touch /tmp/luoahong1.txt
[root@adminset ~]# [ -f /tmp/luoahong1.txt ] ||echo 0
[root@adminset ~]# rm -f /tmp/luoahong1.txt
[root@adminset ~]# [ -f /tmp/luoahong1.txt ] ||echo 0
0
提示:[]命令的选项和test的命令的选项是通用的,因此,使用[]时的参数选项可以通过man test命令获的帮助
文件测试表达式
范例6-5:文件属性条件表达式测试实践
[root@adminset ~]# ls -l luoahong
-rw-r--r-- 1 root root 0 Jun 14 07:48 luoahong
[root@adminset ~]# [ -r luoahong ] && echo 1 ||echo 0
1
#测试luoahong是否可读 [root@adminset ~]# [ -w luoahong ] && echo 1 ||echo 0
1
#测试luoahong是否可写
[root@adminset ~]# [ -x luoahong ] && echo 1 ||echo 0
0
#测试luoahong是否可执行
[root@adminset ~]# chmod 001 luoahong
[root@adminset ~]# ls -l luoahong
---------x 1 root root 0 Jun 14 07:48 luoahong
#修改后的结果
[root@adminset ~]# [ -w luoahong ] && echo 1 ||echo 0
1
#用户权限位明明没有w,为什么还是返回1呢?
[root@adminset ~]# echo 'echo test' >oldboy
#因为确实可以写啊,这是root用户比较特殊的地方
[root@adminset ~]# [ -r luoahong ] && echo 1 ||echo 0
1
#用户权限位明明没有r,为什么还是返回1呢?
[root@adminset ~]# echo 'echo test' >luoahong
[root@adminset ~]#cat luoahong
echo test
#因为确实可以读啊,这是root用户比较特殊的地方。
[root@adminset ~]# [ -x luoahong ] && echo 1 ||echo 0
1
[root@adminset ~]# ./luoahong
[root@adminset ~]# ./luoahong
test #可执行
提示:测试文件的读、写、执行等属性,不光是根据文件属性rwx的表示来判断,
还要看当前执行的用户是否真的可以按照对应的权限操作该文件
测试shell变量示例
root@adminset ~]# file1=/etc/services;file2=/etc/rc.local
[root@adminset ~]# echo $file1 $file2
/etc/services /etc/rc.local
范例:对单个文件变量进行测试
[root@adminset ~]# [ -f "$file1" ] && echo 1 || echo 0
1
[root@adminset ~]# [ -d "$file1" ] && echo 1 || echo 0
0
[root@adminset ~]# [ -s "$file1" ] && echo 1 || echo 0
1
[root@adminset ~]# [ -e "$file1" ] && echo 1 || echo 0
1
[root@adminset ~]#
[root@adminset ~]#
范例:对单个目录或文件进行测试
[root@adminset ~]# [ -e /etc ] && echo 1 || echo 0
1
[root@adminset ~]# [ -w /etc/serbices ] && echo 1 || echo 0
0
[root@adminset ~]# su - luoahong
[luoahong@adminset ~]$ [ -w /etc/servies ] && echo 1 || echo 0
0
#文件不可写,所以返回0
范例:测试变量的特殊写法及问题
用测试变量时,如果被测试的变量不加双引号,那么测试结果可能会不时正确的示例如下:
[luoahong@adminset ~]$ echo $tyx
#这是一个不存在的变量,如果读者已经定义、则可以执行unset取消
[luoahong@adminset ~]$ [ -f $tyx ] && echo 1 || echo 0
1
#命名$tyx变量不存在内容还返回1,逻辑就不对了
[luoahong@adminset ~]$ [ -f "$tyx" ] && echo 1 || echo 0
0
#加了双引号就返回0,逻辑就对了
如果是文件实体路径,那么加引号与不加引号的结果时一样的:
[luoahong@adminset ~]$ [ -f "/etc/services" ] && echo 1 || echo 0
1
[luoahong@adminset ~]$ [ -f /etc/services ] && echo 1 || echo 0
1
范例: 在生产环境下,系统NFS启动脚本的条件测试
more /etc/init.d/nfs # Source networking configuration.
[ -f /etc/sysconfig/network ] && . /etc/sysconfig/network # Check for and source configuration file otherwise set defaults
[ -f /etc/sysconfig/nfs ] && . /etc/sysconfig/nfs # Remote quota server
[ -z "$RQUOTAD" ] && RQUOTAD=`type -path rpc.rquotad`
特别提示:系统脚本时我们学习编程的第一标杆,新手要多参考脚本来学习,虽然有些脚本也不是特别规范
范例:实现系统bind启动脚本named
[luoahong@adminset ~]$ [ -r /etc/sysyconfig/network ] && ./etc/sysconfig/network
#若文件存在且可读,则加载/etc/sysconfig/network
[luoahong@adminset ~]$ [ -x /usr/sbin/$named ] || exit 5
范例:写出简单高效的测试文件
在做测试判断时,不一定非要按照"前面的操作成功了如何,否则如何"的方法来进行。直接做部分判断,有时看起来更简洁
[luoahong@adminset ~]$ [ -x luoahong ] && echo 1
#如果luoahong可执行,则输出1;如果不可执行,则不做任何输出
[luoahong@adminset ~]$ [ -f /etc ] && echo 1
[luoahong@adminset ~]$ [ -f /etc ] && echo 0
#如果l/etc 是文件这一点不成立,则输出0,如果成立则不做任何输出
范例:实现系统脚本/etc/init.d/nfs
[luoahong@adminset ~]$ sed -n '44,50p' /etc/init.d/nfs
# Check that networking is up.
[ "${NETWORKING}" != "yes" ] && exit 6
#如果${NETWORKING}的变量内容不等于yes,则退出 [ -x /usr/sbin/rpc.nfsd ] || exit 5
#如果/usr/sbin/rpc.nfsd的脚本不可执行,则以返回值5退出脚本。如果可执行,则不做任何输出
[ -x /usr/sbin/rpc.mountd ] || exit 5
[ -x /usr/sbin/exportfs ] || exit 5
特殊表达式测试案例
范例:当条件不成立是,执行大括号里的多条命令,这里要使用逻辑操作符||
[root@adminset 06]# sh 6_15.sh
1
2
3
[root@adminset 06]# cat 6_15.sh
[ -f /etc ] || {
echo 1
echo 2
echo 3 } [root@adminset 06]# sh 6_15.sh
1
2
3
如果上述脚本写在一行里面,那么里面的每个命令都需要用分号结尾,示例如下所示:
[root@adminset 06]# [ -f /etc/services ] && { echo "I am luoahong"; echo "I am linuxer"; }
I am luoahong
I am linuxer
提示:本例的两种用法都很简洁,但是不如if条件容易理解,因此请读者根据自身情况选择使用,更多帮助请man test查询
字符串测试表达式
字符串测试操作符
范例:字符串条件表达式测试实践
[root@adminset 06]# [ -n "abc" ] && echo 1 || echo 0
1
[root@adminset 06]# test -n "" && echo 1 || echo 0
0
[root@adminset 06]# var="luoahong"
[root@adminset 06]# [ -n "$var" ] && echo 1 || echo 0
1
[root@adminset 06]# [ -n $var ] && echo 1 || echo 0
1
[root@adminset 06]# var="luoahong1"
[root@adminset 06]# [ -z $var ] && echo 1 || echo 0
0
[root@adminset 06]# [ "abc" = "abd" ] && echo 1 || echo 0
0
[root@adminset 06]# [ "$var" = "luoahong1" ] && echo 1 || echo 0
1
[root@adminset 06]# [ "$var" == "luoahong1" ] && echo 1 || echo 0
1
[root@adminset 06]# [ "$var" != "luoahong1" ] && echo 1 || echo 0
0
字符串测试生产案例
范例:有关双引号和等号两端空格的生产系统标准
[root@adminset 06]# sed -n '30,31p' /etc/init.d/network
#check that networking is up
[ "${NETWORKING}" = "no" ] && exit 6
#字符串变量和字符串都加了双引号,比较符号"="两端也都有空格
范例:系统脚本/etc/init.d/nfs字符串测试的应用示例
[root@adminset 06]# sed -n '65,80p' /etc/init.d/nfs
[ -z "$MOUNTD_NFS_V2" ] && MOUNTD_NFS_V2=default
#-z的应用,如果变量MOUNTD_NFS_V2的长度为0则赋值default
[ -z "$MOUNTD_NFS_V3" ] && MOUNTD_NFS_V3=default
#-z的应用,如果变量MOUNTD_NFS_V3的长度为0则赋值default
# Number of servers to be started by default
[ -z "$RPCNFSDCOUNT" ] && RPCNFSDCOUNT=8 # Start daemons.
[ -x /usr/sbin/rpc.svcgssd ] && /sbin/service rpcsvcgssd start # Set the ports lockd should listen on
if [ -n "$LOCKD_TCPPORT" -o -n "$LOCKD_UDPPORT" ]; then #-n的应用
[ -x /sbin/modprobe ] && /sbin/modprobe lockd $LOCKDARG
[ -n "$LOCKD_TCPPORT" ] && \
/sbin/sysctl -w fs.nfs.nlm_tcpport=$LOCKD_TCPPORT >/dev/null 2>&1
[ -n "$LOCKD_UDPPORT" ] && \
/sbin/sysctl -w fs.nfs.nlm_udpport=$LOCKD_UDPPORT >/dev/null 2>&1
fi
整数变量测试示例
范例:通过[]实现整数条件测试
[root@adminset 06]# a1=98;a2=99
[root@adminset 06]# [ $a1 -eq $a2 ] && echo 1 ||echo 0
0
[root@adminset 06]# [ $a1 -gt $a2 ] && echo 1 ||echo 0
0
[root@adminset 06]# [ $a1 -lt $a2 ] && echo 1 ||echo 0
1
范例:利用[[]]和(())实现直接通过常规数学运算符进行比较
[root@adminset 06]# [[ $a1 > $a2 ]] && echo 1 ||echo 0
0
[root@adminset 06]# [[ $a1 < $a2 ]] && echo 1 ||echo 0
1
[root@adminset 06]# (($a1>=$a2)) && echo 1|| echo 0
0
[root@adminset 06]# (($a1<=$a2)) && echo 1|| echo 0
1
范例:系统脚本中使用整数比较的案例
[root@adminset ~]#grep -w "\-eq" /etc/init.d/nfs
[ $RETVAL -eq 0 ] && RETVAL=$rval #过滤出相等(-eq)的例子
[ $RETVAL -eq 0 ] && RETVAL=$rval #使用[],且两边都要有一个空格
[ $RETVAL -eq 0 ] && RETVAL=$rval #使用"-eq" 的比较操作符的写法
[ $RETVAL -eq 0 ] && RETVAL=$rval
[ $RETVAL -eq 0 ] && RETVAL=$rval [root@adminset ~]#grep -w "\-gt" /etc/init.d/nfs #过滤出大于(-gt)的例子
if [ $cnt -gt 0 ]; then
逻辑操作符实践示例
范例:[]里的逻辑操作配合文件测试表达式使用的示例
[root@adminset 06]# f1=/etc/rc.local;f2=/etc/services
[root@adminset 06]# echo -ne "$f1 $f2\n"
/etc/rc.local /etc/services
[root@adminset 06]# [ -f "$f1" -a -f "$f2" ] && echo 1 || echo 0
1
[root@adminset 06]# [ -f "$f1" -o -f "$f222" ] && echo 1 || echo 0
1
[root@adminset 06]# [ -f "$f111" -o -f "$f222" ] && echo 1 || echo 0
0
[root@adminset 06]# [ -f "$f1" && -f "$f2" ] && echo 1 || echo 0
-bash: [: missing `]'
0
#这是错误的语法,[]中不能用&&||
[root@adminset 06]# [ -f "$f1" ] && [ -f "$f2" ] && echo 1 || echo 0
1
#如果在[]中使用&&,则这样用
范例:[[]]里逻辑操作符配合字符串的条件表达式的测试示例
[root@adminset 06]# a="luoahong";b="tyx"
[root@adminset 06]# echo -ne "$a $b\n"
luoahong tyx
[root@adminset 06]# [[ ! -n " $a" && "$a" = "$b"]] && echo 1 || echo 0
-bash: conditional binary operator expected
-bash: syntax error near `1'
[root@adminset 06]# [[ ! -n "$a" && "$a" = "$b"]] && echo 1 || echo 0
-bash: conditional binary operator expected
-bash: syntax error near `1'
[root@adminset 06]# [[ ! -n "$a" && "$a" = "$b" ]] && echo 1 || echo 0
0
[root@adminset 06]# [[ -z "$a" || "$a" != "$b" ]] && echo 1 || echo 0
1
[root@adminset 06]#
[root@adminset 06]# [[ -z "$a" -o "$a" != "$b" ]] && echo 1 || echo 0
-bash: syntax error in conditional expression
-bash: syntax error near `-o'
范例:(())里逻辑操作符符合整数的条件表达式测试示例
[root@adminset 06]# m=21;n=38
[root@adminset 06]# ((m>20&&n>30)) && echo 1 || echo 0
1
[root@adminset 06]# ((m>20||n>30)) && echo 1 || echo 0
1
[root@adminset 06]# ((m<20||n<30)) && echo 1 || echo 0
0
[root@adminset 06]# ((m<20 -a n<30)) && echo 1 || echo 0
-bash: ((: m<20 -a n<30: syntax error in expression (error token is "n<30")
0
#内部用-a或-o也会报语法错误
范例:使用多个[]号,并通过与或非进行混合测试
[root@adminset 06]# m=21;n=38
[root@adminset 06]# [ $m =gt 20 -a $n -lt 30 ] && echo 1 || echo 0
-bash: [: too many arguments
0
[root@adminset 06]# [ $m gt 20 -a $n -lt 30 ] && echo 1 || echo 0
-bash: [: too many arguments
0
[root@adminset 06]# [ $m -gt 20 -a $n -lt 30 ] && echo 1 || echo 0
0
[root@adminset 06]# [ $m -gt 20 ] || [ $n -lt 30 ] echo 1 || echo 0
[root@adminset 06]# [ $m -gt 20 ] || [ $n -lt 30 ] && echo 1 || echo 0
1 #多个[]号之间用&&或||链接
范例:NFS系统启动脚本中有关[]与或非判断的使用案例
[root@adminset~]#egrep -wn "\-a|\-o" /etc/init.d/nfs
75: if [ -n "$LOCKD_TCPPORT" -o -n "$LOCKD_UDPPORT" ]; then
87: [ "$NFSD_MODULE" != "noload" -a -x /sbin/modprobe ] && {
102: if [ -n "$RQUOTAD" -a "$RQUOTAD" != "no" ]; then
170: if [ -n "$RQUOTAD" -a "$RQUOTAD" != "no" ]; then
209: if [ -n "$RQUOTAD" -a "$RQUOTAD" != "no" ]; then
229: if [ $MOUNTD = 1 -o $NFSD = 1 ] ; then
范例:系统启动脚本中有关[[]]的用法和与或非的使用案例
在操作系统中,[[]]的用法不是很多,并且大多数情况都用于通配符匹配的场景,这里不的不通过大海捞针的
方法(遍历/etc/init.d/下的所有脚本)来帮助大家查找[[]]的用法:
[root@69 ~]# for n in `ls /etc/init.d/*`;do egrep -wn "\[\[ " $n&&echo $n;done
119: if [[ "$dst" == /dev/mapper* ]] \
/etc/init.d/halt
68: if [[ $? = 0 ]]; then
/etc/init.d/httpd
641: if [[ -n "$_target" ]]; then
656: if [[ "$_rmnt" == "$_mnt" ]] || ! is_dump_target_configured; then
/etc/init.d/kdump
50: if [[ $route == *" via "* ]] ; then
75: if ! [[ "$SYSLOGADDR" =~ $IPv4_regex ]] && ! [[ "$SYSLOGADDR" =~ $IPv6_regex ]];then
80: if [[ $? -eq 2 ]]; then
84: if [[ $? -ne 0 ]]; then
/etc/init.d/netconsole
167: if [[ "$rootfs" == nfs* || "$rootopts" =~ _r?netdev ]] ; then
/etc/init.d/network
提示:可见[]中使用-a或-o更常见,[[]]中使用&&或||不常见,使用&&或||链接两个[]的多表达式判断也不常见
shell编程:条件测试与比较(六)的更多相关文章
- Shell编程-条件测试 | 基础篇
什么是Shell Shell是一个命令解释器,它会解释并执行命令行提示符下输入的命令.除此之外,Shell还有另一个功能,如果要执行多条命令,它可以将这组命令存放在一个文件中,然后可以像执行Linux ...
- Shell 编程 条件语句
本篇主要写一些shell脚本条件语句的使用. 条件测试 test 条件表达式 [ 条件表达式 ] 文件测试 -d:测试是否为目录(Directory). -e:测试文件或目录是否存在(Exist). ...
- 关于shell脚本——条件测试、if语句、case语句
目录 一.条件测试 1.1.表达说明 1.2.test命令 文件测试 1.3.整数值比较 1.4.字符串比较 1.5.逻辑测试 二.if语句 2.1.单分支结构 2.2.双分支结构 2.3.多分支结构 ...
- 二、shell 脚本条件测试
目录 一.条件测试 test 格式 文件测试 文件测试常见选项 整数值比较 字符串比较 浮点数的运算 逻辑测试 二.if语句 1单分支 2双分支结构 3多分支结构 三元运算符 三.case 一.条件测 ...
- Linux Shell 03 条件测试
条件测试 方式一:在Bash中 test命令和[]是等价的. test命令: if test $n1 -eq $n2 then echo "The two number are equal& ...
- shell脚本条件测试与比较
1.条件测试常用语法 test 测试表达式 利用test命令进行条件测试表达式,test命令与测试表达式之间至少有一个空格 [ 测试表达式 ] 通过[ ]中括号进行条件测试表达式,[]中括号边界与测试 ...
- shell编程之测试和判断
一.测试 程序运行中经常需要根据实际情况来运行特定的命令或代码段.比如判断某个文件或目录是否存在,如果文件或目录不存在,可能首先创建文件或目录.举例说,要判断文件/var/log/mlocate文件是 ...
- bash编程-条件测试
Shell脚本中经常需要判断某情况或者数据是否满足,需要由测试机制来实现. 测试方式 echo $?查看命令执行状态返回值 bash脚本中可以自定义返回值exit n(n为自己指定的状态码),shel ...
- Linux Shell编程 条件判断语法
if条件判断语句 单分支 if 条件语句 语法格式: if [条件判断式];then 程序 fi 或者 if [条件判断式] then 程序 fi 在使用单分支 if 条件查询时需要注意几点: if ...
- shell编程 条件判断式----利用 case ..... esac 判断
条件判断式----利用 case ..... esac 判断 case $变量名称 in <==关键词为 case ,还有变量前有钱字号 "第一个变量内容") &l ...
随机推荐
- FPGA学习-PS2接口
选自http://m.elecfans.com/article/774143.html
- LeetCode 109——有序链表转化二叉搜索树
1. 题目 2. 解答 2.1. 方法一 在 LeetCode 108--将有序数组转化为二叉搜索树 中,我们已经实现了将有序数组转化为二叉搜索树.因此,这里,我们可以先遍历一遍链表,将节点的数据存入 ...
- C#程序 权限不够的解决方案
有时候需要操作硬件,或者启动windows服务程序时,系统会提示很多奇怪的问题,归根结底就是程序当前所拥有的权限不够,需要提升,以前我们时手写一个manifest,多不容易啊, 现在有正常的方法了 1 ...
- POJ 3845 Fractal(计算几何の旋转缩放)
Description Fractals are really cool mathematical objects. They have a lot of interesting properties ...
- Python字符串中的r前缀
在Python中,如果字符串的前面有r/R前缀,那么,就会禁用转义符\的功能: >>>path = r'C:\new\text.dat' >>>pah 'C:\\n ...
- string && 字符数组
一.string 1. 使用字符串字面值初始化string对象 如:string s1 = "hiya"; string s2("hiya"); 该字面值的最后 ...
- python爬虫--打开爬取页面
def requests_view(response): import webbrowser requests_url = response.url base_url = '<head>& ...
- 【重读MSDN之ADO.NET】ADO.NET连接
连接到ADO.NET中的数据源 在 ADO.NET 中,通过在连接字符串中提供必要的身份验证信息,使用 Connection 对象连接到特定的数据源.使用的 Connection 对象取决于数据源的类 ...
- 简述在akka中发送消息的过程
在flink的数据传输过程中,有两类数据,一类数据是控制流数据,比如提交作业,比如连接jm,另一类数据是业务数据.flink对此采用了不同的传输机制,控制流数据的传输采用akka进行,业务类数据传输在 ...
- 【python】 requirements使用方法
记得导入导出包的时候要想激活虚拟环境.1.导出requirements方法pip freeze > requirements.txt 2.安装requirements方法pip install ...