条件测试方法综述

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编程:条件测试与比较(六)的更多相关文章

  1. Shell编程-条件测试 | 基础篇

    什么是Shell Shell是一个命令解释器,它会解释并执行命令行提示符下输入的命令.除此之外,Shell还有另一个功能,如果要执行多条命令,它可以将这组命令存放在一个文件中,然后可以像执行Linux ...

  2. Shell 编程 条件语句

    本篇主要写一些shell脚本条件语句的使用. 条件测试 test 条件表达式 [ 条件表达式 ] 文件测试 -d:测试是否为目录(Directory). -e:测试文件或目录是否存在(Exist). ...

  3. 关于shell脚本——条件测试、if语句、case语句

    目录 一.条件测试 1.1.表达说明 1.2.test命令 文件测试 1.3.整数值比较 1.4.字符串比较 1.5.逻辑测试 二.if语句 2.1.单分支结构 2.2.双分支结构 2.3.多分支结构 ...

  4. 二、shell 脚本条件测试

    目录 一.条件测试 test 格式 文件测试 文件测试常见选项 整数值比较 字符串比较 浮点数的运算 逻辑测试 二.if语句 1单分支 2双分支结构 3多分支结构 三元运算符 三.case 一.条件测 ...

  5. Linux Shell 03 条件测试

    条件测试 方式一:在Bash中 test命令和[]是等价的. test命令: if test $n1 -eq $n2 then echo "The two number are equal& ...

  6. shell脚本条件测试与比较

    1.条件测试常用语法 test 测试表达式 利用test命令进行条件测试表达式,test命令与测试表达式之间至少有一个空格 [ 测试表达式 ] 通过[ ]中括号进行条件测试表达式,[]中括号边界与测试 ...

  7. shell编程之测试和判断

    一.测试 程序运行中经常需要根据实际情况来运行特定的命令或代码段.比如判断某个文件或目录是否存在,如果文件或目录不存在,可能首先创建文件或目录.举例说,要判断文件/var/log/mlocate文件是 ...

  8. bash编程-条件测试

    Shell脚本中经常需要判断某情况或者数据是否满足,需要由测试机制来实现. 测试方式 echo $?查看命令执行状态返回值 bash脚本中可以自定义返回值exit n(n为自己指定的状态码),shel ...

  9. Linux Shell编程 条件判断语法

    if条件判断语句 单分支 if 条件语句 语法格式: if [条件判断式];then 程序 fi 或者 if [条件判断式] then 程序 fi 在使用单分支 if 条件查询时需要注意几点: if ...

  10. shell编程 条件判断式----利用 case ..... esac 判断

    条件判断式----利用 case ..... esac 判断 case  $变量名称 in   <==关键词为 case ,还有变量前有钱字号 "第一个变量内容")   &l ...

随机推荐

  1. Ext JS 6学习文档-第3章-基础组件

    Ext JS 6学习文档-第3章-基础组件 基础组件 在本章中,你将学习到一些 Ext JS 基础组件的使用.同时我们会结合所学创建一个小项目.这一章我们将学习以下知识点: 熟悉基本的组件 – 按钮, ...

  2. 文件操作---基于python

    # coding:utf-8from time import sleepimport sysreload(sys)sys.setdefaultencoding("utf8")f=o ...

  3. PHPCMS调取当前栏目的描述、文章位置导航、当前栏目链接、当前栏目名称

    当我们填写了栏目描述,怎么调用出来. 使用 {$CATEGORYS[$catid][description]} 就可以把栏目的描述调用出来 下面三个也比较常用{catpos($catid)} 显示文章 ...

  4. OSG配置捷径,VS2013+WIN10

    在自己电脑上用CMAKE已经编译好了,上传到百度云里面了. 环境是WIN10+VS2013. 链接:http://pan.baidu.com/s/1hrO7GFE 密码:fwkw 解压之后放在C盘或者 ...

  5. 修改IntelliJ IDEA字体

  6. 初入py

    1.下载工具sublime 我的网盘下载地址:https://pan.baidu.com/s/18-U1ZSg_zHoSAqUuvXj_PQ 直接解压即可 2.配置py27 在新建的文件里面编辑并保存 ...

  7. SQL SERVER 存储过程中SELECT 返回值如何赋值给变量

    今天在处理一个问题时,使用到一个存储过程,是用于更新并获取最新ID的.在使用过程中,需要获取到这个ID并赋值给变量,结果用EXEC @ID = 存储过程的方式获取失败了.具体情况如下: 为了还原整个情 ...

  8. bzoj2257[POI2011]Programming Contest

    首先可以费用流建图,左边一堆点表示人,右边一堆点表示题,源点向每个人连floor(t/r)条边,费用依次为r,2r,3r….然后写了一个卡不过去,动态加边也卡不过去,然后我想:这里一定有一些不为人知的 ...

  9. axios post提交数据格式不对的问题

    需要格式化一下 this.$http({ method: "post", url: "/chinacountry/index.php/home/Search/index& ...

  10. harbor1.4.0高可用部署

    一.对象冒充 其原理如下:构造函数使用 this 关键字给所有属性和方法赋值(即采用类声明的构造函数方式).因为构造函数只是一个函数,所以可使 Parent 构造函数成为 Children 的方法,然 ...