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 ...
随机推荐
- solidity python 签名和验证
注意,以太坊智能合约里面采用的是公钥非紧凑类型 def gen_secrets_pair(): """ 得到公钥和私钥 :return: ""&quo ...
- NMAP-高级用法
1.报文分段 2.偏移 –mtu后面的数字是8的倍数 3.源端口欺骗 4.指定报文长度 5.ttl 6.mac地址伪造 0代表随机伪造 7.正常输出 8.输出为xml 9.输出为grep 10.输出所 ...
- Line belt(三分镶嵌)
In a two-dimensional plane there are two line belts, there are two segments AB and CD, lxhgww's spee ...
- Thunder团队第二周 - Scrum会议6
Scrum会议6 小组名称:Thunder 项目名称:爱阅app Scrum Master:宋雨 工作照片: 邹双黛同学在拍照,所以不再照片中. 参会成员: 王航:http://www.cnblogs ...
- Notes of the scrum meeting before publishing(12.17)
meeting time:18:30~20:30p.m.,December 17th,2013 meeting place:3号公寓一层 attendees: 顾育豪 ...
- JavaScript初探系列之Ajax应用
一 什么是Ajax Ajax是(Asynchronous JavaScript And XML)是异步的JavaScript和xml.也就是异步请求更新技术.Ajax是一种对现有技术的一种新的应用,不 ...
- lintcode-160-寻找旋转排序数组中的最小值 II
160-寻找旋转排序数组中的最小值 II 假设一个旋转排序的数组其起始位置是未知的(比如0 1 2 4 5 6 7 可能变成是4 5 6 7 0 1 2). 你需要找到其中最小的元素. 数组中可能存在 ...
- FromHandle临时对象一探究竟
我们在调用CWnd::GetDlgItem()函数时,MSDN告诉我们:The returned pointer may be temporary and should not be stored f ...
- 记一次dll强命名冲突事件
一 问题的出现 现在要做一个net分布式平台,平台涉及多个服务之间调用问题,最基础的莫过于sso.由于我们的sso采用了wcf一套私有框架实现,另外一个webapi服务通过接口调用sso服务.由于s ...
- 【Docker 命令】- top命令
docker top :查看容器中运行的进程信息,支持 ps 命令参数. 语法 docker top [OPTIONS] CONTAINER [ps OPTIONS] 容器运行时不一定有/bin/ba ...