条件测试方法综述

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. kafka stream 低级别的Processor API动态生成拓扑图

    public class KafkaSream { public static void main(String[] args) { Map<String, Object> props = ...

  2. 统计单词数:string函数使用

    题目描述 一般的文本编辑器都有查找单词的功能,该功能可以快速定位特定单词在文章中的位置,有的还能统计出特定单词在文章中出现的次数. 现在,请你编程实现这一功能,具体要求是:给定一个单词,请你输出它在给 ...

  3. 基础数据类型-list

    序列是python中的基础数据结构,序列里每一个元素都有一个下标,从0开始,依次递增. list,tuple,dictionary是使用最频繁的三类数据结构. (1)序列都有的方法包括:索引,切片,检 ...

  4. 使用 letter-space 后文字不能居中解决

    letter-space:2em; text-align: center; 使用letter-space后和上面的字体对比明显没有居中: 选定元素后发现,每个字后面都被加了2em,不是不能居中而是因为 ...

  5. 第一章 Windows编程基础(1~4课)

    第一课:从main到WinMain 第二课:窗口和消息 第三课:MFC编程 第四课:MFC应用程序框架 概括: Win32的两种编程框架:SDK方式.MFC方式 1. SDK方式:使用WinMain入 ...

  6. 采用c#实现功能1

    看了好多c#的菜鸟教程不如自己开始动手打代码,最终实现了功能一,参考了网上的wordcount代码发现无论是c++还是c#大部分采用的是哈希表的方法实现的,本来还想仅用循环实现遍历句子中的所有字符,即 ...

  7. JavaScript初探系列之日期对象

    时间对象是一个我们经常要用到的对象,无论是做时间输出.时间判断等操作时都与这个对象离不开.它是一个内置对象——而不是其它对象的属性,允许用户执行各种使用日期和时间的过程. 一   Date 日期对象 ...

  8. Windows资源监控工具大全

    在利用LoadRunner进行性能测试的时候,Windows服务器的资源是经常需要监控的对象.其实除了LoadRunner提供的计数器,似乎Window服务器并不像Unix或者Linux提供众多的性能 ...

  9. new关键字 、this关键字、base关键字

    使用new,所做的三件事: 1. (类是引用对象,引用对象是在堆中开辟空间)在堆中开辟空间 2. 在开辟的堆空间中创建对象 3. 调用对象的构建函数 4. 隐藏父类成员:子类的成员可以与隐藏从父类继承 ...

  10. shiro学习详解(开篇)

    一.前言 要开始接触公司另外一个项目了,RX和我说了下整个项目框架的结构,其中提到权限的控制是通过shiro来处理的,对我而言又是一个全新的知识点,于是今天花了一点时间去学习shiro的使用,看了好几 ...