shell脚本的条件判断3:探究[[]]和[]的区别

news2025/7/14 1:48:39

前言

实例中除非特别标注,否则都不是在centos中测试的。

一 简述 

多数情况下[]和[[]]是可以通用的,两者的主要差异是:test或[]是符合POSIX标准的测试语句,兼容性更强,几乎可以运行在所有Shell解释器中,相比较而言[[]]仅可运行在特定的几个Shell解释器中(如Bash、Zsh等)。事实上,目前支持使用[[]]进行条件测试的解释器已经足够多了。使用[[]]进行测试判断时甚至可以使用正则表达式。

二 实例对比  

首先,测试两者的通用表达式(同样,一定要注意空格的问题,空格不可或缺)。 

相同点

csdn@ubuntu:~$ [[ 5 -eq 5 ]] && echo Y || echo N
Y
csdn@ubuntu:~$ [[ -r main.c ]] && echo Y || echo N
N
csdn@ubuntu:~$ [[ -r other.c ]] && echo Y || echo N
Y
csdn@ubuntu:~$ [ 5 -eq 5 ] && echo Y || echo N
Y
csdn@ubuntu:~$ [ -r main.c ] && echo Y || echo N
N
csdn@ubuntu:~$ [ -r other.c ] && echo Y || echo N
Y
csdn@ubuntu:~$

排序的区别 

看两者的差异点。其中,在[[]]中使用<和>符号时,系统进行的是排序操作,而且支持在测试表达式内使用&&和||符号。在test或[]测试语句中不可以使用&&和||符号。

注意 

[[ ]]中的表达式如果使用<或>进行排序比较,使用的是本地的locale语言顺序。可以使用LANG=C设置在排序时使用标准的ASCII码顺序。

在ASCII码的顺序中,小写字母顺序码>大写字母顺序码>数字顺序码。

我的系统默认LANG值是zh_CN.UTF-8,所说义[]和[[]]的排序结果是不同的。

csdn@ubuntu:~$ echo $LANG
zh_CN.UTF-8
csdn@ubuntu:~$ [ a > A ] && echo Y || echo N
Y
csdn@ubuntu:~$ [[ a > A ]] && echo Y || echo N
N
csdn@ubuntu:~$

 修改LANG=C

csdn@ubuntu:~$ LANG=C
csdn@ubuntu:~$ [[ a > A ]] && echo Y || echo N
Y
csdn@ubuntu:~$ [ a > A ] && echo Y || echo N
Y
csdn@ubuntu:~$

条件中的与或区别 

虽然[]也支持同时进行多个条件的逻辑测试,但是在[]中需要使用-a和-o进行逻辑与和逻辑或的比较操作,而[[]]中可以直接使用&&和||进行逻辑比较操作,更直观,可读性更好。A && B或者A -a B,意思是仅当A和B两个条件测试都成功时,整体测试结果才为真。A || B或者A -o B,意思是只要A或B中的任意一个条件测试成功,则整体测试结果为真。

csdn@ubuntu:~$ [ y == y -a n == n ] && echo Y || echo N
Y
csdn@ubuntu:~$ [ y == n -o n == n ] && echo Y || echo N
Y
csdn@ubuntu:~$ [ y == n -a n == n ] && echo Y || echo N
N
csdn@ubuntu:~$ [ y == n -o n == n ] && echo Y || echo N
Y
csdn@ubuntu:~$ [ y == n -o n == y ] && echo Y || echo N
N
csdn@ubuntu:~$ [[ y == n &&  n == y ]] && echo Y || echo N
N
csdn@ubuntu:~$ [[ y == y ||  n == y ]] && echo Y || echo N
Y
csdn@ubuntu:~$ [[ y == y || n == y ]] && echo Y || echo N
Y
csdn@ubuntu:~$ [[ y == n || n == y ]] && echo Y || echo N
N
csdn@ubuntu:~$

 需要注意的还有==比较符,在[[]]中==是模式匹配,模式匹配允许使用通配符。例如,Bash常用的通配符有*、? 、[…]等。而==在test语句中仅代表字符串的精确比较,判断字符串是否一模一样。下面的例子,测试变量name的值是否以字母c开头,后面可以是任意长度的任意字符,测试结果为真。总是使用之前多测试吧,感觉不太靠谱的样子。

csdn@ubuntu:~$ name=csdn
csdn@ubuntu:~$ [[ $name == c* ]] && echo Y || echo N
Y
csdn@ubuntu:~$ [[ $name == c... ]] && echo Y || echo N
N
csdn@ubuntu:~$ [[ $name == c* ]] && echo Y || echo N
Y
csdn@ubuntu:~$ [[ $name == c[a-z]* ]] && echo Y || echo N
Y
csdn@ubuntu:~$ [[ $name == c[a-z]{3} ]] && echo Y || echo N
N
csdn@ubuntu:~$ [[ $name == c[.]{3} ]] && echo Y || echo N
N
csdn@ubuntu:~$ [[ $name == c[.]{4} ]] && echo Y || echo N
N
csdn@ubuntu:~$

接着,测试变量name的值是否以字母d开头,后面可以是任意长度的任意字符,测试结果为假。 

csdn@ubuntu:~$ [[ $name == d* ]] && echo Y || echo N
N
csdn@ubuntu:~$

 测试变量name的值是否是c和dn中间有任意单个字符?结果为真

csdn@ubuntu:~$ [[ $name == c?dn ]] && echo Y || echo N
Y
csdn@ubuntu:~$

测试字符a,是否是小写字母?结果为真。

csdn@ubuntu:~$ [[ a == [a-z] ]] && echo Y || echo N
Y
csdn@ubuntu:~$

 同样是使用==进行比较操作,但在[]中系统进行的是字符串的比较操作,判断两个字符串是否绝对相同。

下面是在ubuntu中测试的,会报错的。 

csdn@ubuntu:~$ [ c == c ] && echo Y || echo N
Y
csdn@ubuntu:~$ [ c == c* ] && echo Y || echo N
bash: [: too many arguments
N
csdn@ubuntu:~$

 下面的是在centOS7中测试的,不会报错:

[lkmao@MiWiFi-R3600-srv root]$ [ c == c* ] && echo Y || echo N
N
[lkmao@MiWiFi-R3600-srv root]$ name=csdn
[lkmao@MiWiFi-R3600-srv root]$ [ $name == c* ] && echo Y || echo N
N
[lkmao@MiWiFi-R3600-srv root]$ 

另外,在[[]]中还支持使用=~进行正则匹配,而在[]中则完全不支持正则匹配。对变量name的值进行正则匹配,判断name的值是否包含字母c。

csdn@ubuntu:~$ [[ $name =~ c ]] && echo Y || echo N
Y
csdn@ubuntu:~$

 对变量name的值进行正则匹配,判断name的值是否包含数字。

csdn@ubuntu:~$ [[ $name =~ [0-9] ]] && echo Y || echo N
N
csdn@ubuntu:~$

 对变量name的值进行正则匹配,判断name的值是否包含小写和大写字母。

csdn@ubuntu:~$ [[ $name =~ [a-z] ]] && echo Y || echo N
Y
csdn@ubuntu:~$ name=Csdn
csdn@ubuntu:~$ [[ $name =~ [a-z] ]] && echo Y || echo N
Y
csdn@ubuntu:~$ [[ $name =~ [A-Z] ]] && echo Y || echo N
Y
csdn@ubuntu:~$

 最后,看看分组测试。使用()进行分组,效果类似于虽然在数学上默认先算乘除法再算加减法,但使用()后可以先算加减法再算乘除法。

下面这条命令,在a==a为真的情况下,b==b和c==d两个测试中只要有一个测试为真,则整体测试为真。多测几个值总是好的。测试原理中分条件测试、分支测试、路径测试。总之要测全,搞不好,你正在用的shell就不兼容某种用法。

csdn@ubuntu:~$ [[ a == a ]] && echo Y || echo n
Y
csdn@ubuntu:~$ [[ a == a ]] && echo Y || echo N
Y
csdn@ubuntu:~$ [[ a == a && (b == b) ]] && echo Y || echo N
Y
csdn@ubuntu:~$ [[ a == a && ((b == b) && (c == c)) ]] && echo Y || echo N
Y
csdn@ubuntu:~$ [[ a == a && ((b == b) && (c == d)) ]] && echo Y || echo N
N
csdn@ubuntu:~$ [[ a == a && ((b == b) || (c == d)) ]] && echo Y || echo N
Y
csdn@ubuntu:~$

 终于学到尾声了。快吐了。

列出了[[]]和[]的差异汇总信息,相同点这里不再赘述。为了熟练掌握这些语法,本书后面的案例中将混合应用多种不同的条件测试语句。

小结 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/38280.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

驱动保护进程 句柄降权 杀软自保 游戏破图标技术原理和实现

文章目录实现效果实现原理代码实现实现效果句柄降权对抗(实现破游戏图标和关闭杀软自保)降权对抗延伸游戏降权对抗杀软自保对抗隐藏Object钩子回调完整代码实现效果 效果如图所示: 无法结束进程: CE无图标: 内存无法读取 可以看到被保护的进…

STC 51单片机41——汇编 串口连续发送数据

; 仿真时,单步运行,记得设置虚拟串口数据 ORG 0000H MOV TMOD ,#20H ;定时器1,工作方式2,8位重装载 MOV TH1,#0FDH ; 波特率9600 MOV TL1,#0FDH SETB TR1 ; 启动T1 MOV SCON ,#40H ; 串口工作方式1 …

[激光原理与应用-20]:《激光原理与技术》-6- 谐振腔的结构、作用、工作原理

目录 第1章 谐振腔简介 1.1 什么是谐振腔 1.2 什么是光学谐振腔 1.3 谐振腔的作用 1.4 什么是镜片镀膜 第2章 谐振腔的结构与工作原理 2.1 谐振腔的结构 2.2 谐振腔的分类 2.3 激活介质与谐振腔的工作原理 第1章 谐振腔简介 1.1 什么是谐振腔 谐振腔,是…

[Java反序列化]—CommonsCollections4

0x01: 这条链子 前半段跟CC3 一样 ,都是动态加载字节码的过程,后边的构造用到了两个类,PriorityQueue和TransformingComparator Gadget chain:ObjectInputStream.readObject()PriorityQueue.readObject()...TransformingComparat…

如何Cisco的学员 摆脱游客登录

Cisco Packet Tracer 是一款强大的网络模拟工具,可用于在虚拟实验环境中练习网络、物联网和网络安全技能。您不需要任何硬件,即可获得实操经验! 相信很多小伙伴在使用cisco packet tracer这个思科数据包跟踪器 - 网络仿真工具时在登录的时候…

云原生k8s的前世今生--Docker

不可修改(immutability)和幂等性(idempotent)是一致依赖困扰软件发布与运维的两个难题。以nodejs等解析执行的应用而言,如何控制发布后的软件不被修改运行,发布后,经常发现因为运行环境差异导致各种水土不服:比如应用程序对底层操…

【C++数据结构】渐近记法

渐近记法 3.1 引言 考察程序的操作计数和执行步数有两个重要的原因: 1)预测程序运行时间如何随着实例特征的变化而变化; 2)对两个功能相同的程序,比较它们的时间复杂度。 存在问题: 在使用操作计数时,我们关注的…

Vue生命周期--Vue实例创建过程详解

每个Vue实例在被创建时都要经过一系列的初始化过程--例如,需要设置数据监听、编译模板、将实例挂载到DOM并在数据变化时更新DOM等。同时在这个过程中也会运行一些叫做 生命周期钩子的函数,这给了用户在不同阶段添加自己的代码的机会。 生命周期图示&…

Linux入侵排查

Linux入侵排查 实验内容 当系统被黑客入侵、需短时间查找入侵来源,还原入侵事故过程,同时给出解决方案与防范措施。以下给出一些入侵排查思路 netstat -antpl 查看当前端口状态是LISTEN的端口 针对对外开放的端口,查看日志 先查看ssh爆破的…

OpenGL ES 学习(三) -- 绘制平面图形

上一章中,已经对 OpenGL 的编程语言 GLSL 和渲染模式有了一定的了解,今天,将运用之前的知识,完成一些平面图形的操作。效果如下: 如果你对 OpenGL 的基本概念或者渲染流程不清晰,建议先看 OpenGL ES 学习…

D. Insert a Progression(绝对值的性质)

Problem - 1671D - Codeforces 给你一个n个整数的序列a1,a2,...,an。你还得到了x个整数1,2,...,x。 每个整数可以插入序列的开头,也可以插入序列的结尾,或者插入序列的任何元素之间。 所得序列a′的得分是其中相邻元素的绝对差异之和(∑i1n…

实验跟踪

管理和跟踪机器学习实验。 Intuition 到目前为止,一直在训练和评估不同的基线,但还没有真正跟踪这些实验。将解决这个问题,但定义一个适当的实验跟踪过程,将用于所有未来的实验(包括超参数优化)。实验跟踪是…

【JavaWeb】CookieSession

文章目录一.Cookie❤️1.Cookie的概念2.创建Cookie3.获取Cookie4.修改Cookie的值5.Cookie的生命周期控制6.Cookie有效路径Path的设置7.免输入用户名登录二.Session❤️1.session的概念2.Session的创建和获取3.Session域数据的存取4.Session的生命周期控制5.浏览器和Session之间…

pytorch深度学习实战lesson28

第二十八课 resnet的梯度计算(如何缓解梯度问题) 沐神说:“假设你在卷积神经网络里面,只要了解一个神经网络的话,你就了解 rest net 就行了。 rest net 是一个很简单的也是很好用的一个网络。这也是大家会经常在实际中…

OpenCV-Python小应用(六):车道线检测

OpenCV-Python小应用(六):车道线检测前言前提条件实验环境基于霍夫变换的车道线检测参考文献前言 本文是个人使用OpenCV-Python的应用案例,由于水平有限,难免出现错漏,敬请批评改正。更多精彩内容&#xff…

【成为红帽工程师】第五天 NFS服务器

目录 一、NFS服务器简介 二、NFS的使用 三、客户端使用autofs自动挂载 四、相关实验 一、NFS服务器简介 NFS(网络文件系统),是FreeBSD支持的文件系统中的一种,它允许网络中的计算机(不同的计算机、不同的操作系统&…

Go学习之路:流程控制语句:for、if、else、switch 和 defer(DAY 1)

文章目录前引流程控制语句:for、if、else、switch 和 defer1.1、for循环语句/语法格式(一)1.2、for循环语句/省略前置后置语句(二)1.3、for循环语句/while(三)1.4、for循环语句/无限循环&#x…

美新科技过会:收入依赖美国、产能利用率低,林东亮等均为香港籍

11月25日,深圳证券交易所创业板披露的信息显示,美新科技股份有限公司(下称“美新科技”)获得上市委会议通过。据贝多财经了解,美新科技于2022年3月31日在创业板递交上市申请。 本次冲刺创业板上市,美新科技…

SpringCloudGateway--谓词(断言)

目录 一、定义 二、谓词使用 1、After 2、Before 3、Between 4、Cookie 5、Header 6、Host 7、Method 8、Path 9、Query 10、RemoteAddr 11、Weight 一、定义 SpringCloudGateway中三个重要词汇: 路由(Route):配置网…

傻白入门芯片设计,芯片键合(Die Bonding)(四)

目录 一、键合( Bonding) 1. 什么是键合(Bonding)? 2. 芯片键合步骤 3.芯片拾取与放置(Pick & Place) 4. 芯片顶出(Ejection)工艺 5. 使用环氧树脂(Epoxy)实现粘合的芯片键合工艺 6. 使用晶片黏结薄膜(DAF)的芯片键合工…