[[ ]]是 Shell 内置关键字,它和 test 命令类似,也用来检测某个条件是否成立。

test 能做到的,[[ ]] 也能做到,而且 [[ ]] 做的更好;test 做不到的,[[ ]] 还能做到。可以认为 [[ ]] 是 test 的升级版,对细节进行了优化,并且扩展了一些功能。

[[ ]] 的用法为:

[[ expression ]]

当 [[ ]] 判断 expression 成立时,退出状态为 0,否则为非 0 值。注意[[ ]]expression之间的空格,这两个空格是必须的,否则会导致语法错误。

[[ ]] 不需要注意某些细枝末节

[[ ]] 是 Shell 内置关键字,不是命令,在使用时没有给函数传递参数的过程,所以 test 命令的某些注意事项在 [[ ]] 中就不存在了,具体包括:

  • 不需要把变量名用双引号""包围起来,即使变量是空值,也不会出错。
  • 不需要、也不能对 >、< 进行转义,转义后会出错。

请看下面的演示代码:

#!/bin/bash

read str1
read str2 if [[ -z $str1 ]] || [[ -z $str2 ]] #不需要对变量名加双引号
then
echo "字符串不能为空"
elif [[ $str1 < $str2 ]] #不需要也不能对 < 进行转义
then
echo "str1 < str2"
else
echo "str1 >= str2"
fi

运行结果:
http://c.biancheng.net/shell/
http://data.biancheng.net/
str1 < str2

[[ ]] 支持逻辑运算符

对多个表达式进行逻辑运算时,可以使用逻辑运算符将多个 test 命令连接起来,例如:

[ -z "$str1" ] || [ -z "$str2" ]

你也可以借助选项把多个表达式写在一个 test 命令中,例如:

[ -z "$str1" -o -z "$str2" ]

但是,这两种写法都有点“别扭”,完美的写法是在一个命令中使用逻辑运算符将多个表达式连接起来。我们的这个愿望在 [[ ]] 中实现了,[[ ]]  支持 &&、|| 和 ! 三种逻辑运算符。

使用 [[ ]] 对上面的语句进行改进:

[[ -z $str1 || -z $str2 ]]

这种写法就比较简洁漂亮了。

注意,[[ ]] 剔除了 test 命令的-o-a选项,你只能使用 || 和 &&。这意味着,你不能写成下面的形式:

[[ -z $str1 -o -z $str2 ]]

当然,使用逻辑运算符将多个 [[ ]] 连接起来依然是可以的,因为这是 Shell 本身提供的功能,跟 [[ ]] 或者 test 没有关系,如下所示:

[[ -z $str1 ]] || [[ -z $str2 ]]

该表总结了各种写法的对错
test 或 [] [[ ]]
[ -z "$str1" ] || [ -z "$str2" ] [[ -z $str1 ]] || [[ -z $str2 ]]
[ -z "$str1" -o -z "$str2" ] [[ -z $str1 -o -z $str2 ]] ×
[[ -z $str1 || -z $str2 ]] × [[ -z $str1 || -z $str2 ]]

[[ ]] 支持正则表达式

在 Shell [[ ]] 中,可以使用=~来检测字符串是否符合某个正则表达式,它的用法为:

[[ str =~ regex ]]

str 表示字符串,regex 表示正则表达式。

下面的代码检测一个字符串是否是手机号:

  1. #!/bin/bash
  2. read tel
  3. if [[ $tel =~ ^1[0-9]{10}$ ]]
  4. then
  5. echo "你输入的是手机号码"
  6. else
  7. echo "你输入的不是手机号码"
  8. fi

运行结果1:
13203451100
你输入的是手机号码

运行结果2:
132034511009
你输入的不是手机号码

^1[0-9]{10}$的说明:

  • ^匹配字符串的开头(一个位置);
  • [0-9]{10}匹配连续的十个数字;
  • $匹配字符串的末尾(一个位置)。

本文并不打算讲解正则表达式的语法,不了解的读者请猛击《正则表达式30分钟入门教程》。

总结

有了 [[ ]],你还有什么理由使用 test 或者 [ ],[[ ]] 完全可以替代之,而且更加方便,更加强大。

但是 [[ ]] 对数字的比较仍然不友好,所以我建议,以后大家使用 if 判断条件时,用 (()) 来处理整型数字,用 [[ ]] 来处理字符串或者文件。

Shell [[]]详解:检测某个条件是否成立的更多相关文章

  1. .NET DLL 保护措施详解(五)常规条件下的破解

    为了证实在常规手段破解下能有效保护程序核心功能(演示版本对AES加解密算法及数据库的密钥(一段字符串)进行了保护),特对此DLL保护思路进行相应的测试,包含了反编译及反射测试,看是否能得到AES加解密 ...

  2. Linux的Bash Shell详解

    一.Bash Shell概述 1.什么是bash         bash是Bourne Again Shell的简称,是从unix系统中的sh发展而来的,是用户和Linux内核交互的工具,用户通过b ...

  3. hadoop shell 详解

    概述  所有的hadoop命令均由bin/hadoop脚本引发.不指定参数运行hadoop脚本会打印所有命令的描述.  用法: hadoop [--config confdir] [COMMAND] ...

  4. SHELL 详解

    http://blog.csdn.net/vah101/article/details/6173488 ( a=2;b=4;c=9; ) 子shell 环境 { a=2;b=4;c=9; } 当前sh ...

  5. 每篇半小时1天入门MongoDB——3.MongoDB可视化及shell详解

    本篇主要介绍MongoDB可视化操作以及shell使用及命令,备份恢复.数据导入导出. MongoVUE安装和简单使用 使用mongo.exe 管理数据库虽然可行,功能也挺强大,但每次都要敲命令,即繁 ...

  6. Linux之shell详解

    Shell是什么 Shell 是一个用 C 语言编写的程序,它是用户使用 Linux 的桥梁.Shell 既是一种命令语言,又是一种程序设计语言.Shell 是指一种应用程序,这个应用程序提供了一个界 ...

  7. Impala shell详解

    不多说,直接上干货! 查看帮助文档 impala-shell -h 刷新整个云数据 impala-shell -ruse impala;show tables; 去格式化,查询大数据量时可以提高性能 ...

  8. Shell—详解$0、$1、$2、$#、$*、$@、$?、$$变量

    预定义变量:常用来获取命令行的输入 变量 作用 $0 当前Shell脚本本身的文件名称 $1 脚本接收的第一个参数($1-$9:第1-9个命令行参数名) $2 脚本接收的第二个参数($1-$9:第1- ...

  9. Shell—详解$( )、$(( ))、``与${ }的区别

    https://www.jianshu.com/p/2237f029c385 https://www.cnblogs.com/chenpython123/p/11052276.html https:/ ...

随机推荐

  1. Android开发——回调(Callback)

    1. 回调函数的定义: 在A类中定义了一个方法,这个方法中用到了一个接口和该接口中的抽象方法,但是抽象方法没有具体的实现,需要B类去实现,B类实现该方法后,它本身不会去调用该方法,而是传递给A类,供A ...

  2. 群晖修改启用root账号密码

    DSM6.0以后,官方修改了系统的ROOT密码;需要修改才能启用并使用 软件准备 PUTTY点击下载 DSM中开启SSH 控制面板-终端机和SNMP-启动SSH 打开PUTTY 输入DSM IP地址 ...

  3. windows 之间远程大文件传输问题解决

    今天我在远程登录另一台windows的时候,需要传输一个大约3GB的文件,但是每每经过了一会儿,就会提示我未知错误问题. 我在网上找了一下,本问题的解决方法如下. 1.打开远程登录的对话窗口 2.选择 ...

  4. window下Mysql 恢复Delete删除的数据

    转载:https://www.cnblogs.com/q149072205/p/11940591.html 本机用的Navicat连mysql测试DB又连了正式DB,因为本地与正式要频繁操作所以都打开 ...

  5. usb需要做的工作

    1. QStringList qlist = var2.split('&', QString::SkipEmptyParts); if (qlist.size() >= 2) { usb ...

  6. 关系型数据库---MYSQL---系统学习

    1.概述 1.1 mysql数据库是一种  客户端/服务器体系  的 数据库系统: 服务器部分 在启动运行后没有人机界面,所以终端用户  无法直接使用MySQL: 对MySQL数据库进行访问.操作  ...

  7. asp.net core Mvc 增删改查

    1.创建项目 创建Data文件夹 创建实体类Students/cs public class Students { public Guid Id { get; set; } public string ...

  8. vue 项目 跳转 页面 不刷新 问题

    vue项目中需要导出下载客户数据,因为数据太多,响应太慢.后台直接上传给七牛  然后返回一个下载链接  前端通过跳转链接 来下载 riskManagementApi.friendExprotAll(t ...

  9. Spring Cloud Alibaba 从孵化到 "挂牌" 之旅

    背景 2014 年,Spring Boot 1.0 发布.Spring Boot 的发布绝对是 Pivotal 历史上具有里程碑意义的事件,它让我们能够非常简便地开发 Spring 应用,屏蔽了各种配 ...

  10. NOIp2018集训test-10-21 (联考六day1)

    今天被高一狂踩,两个手抖,t1一个1写成2,t3一个+=写成=,所谓失之毫厘谬以千里,直接丢了50分. 完全背包 看到背包体积如此之大物品体积如此之小容易很想到贪心,肯定要先加很多很多的性价比最高的最 ...