您的位置:首页 > 运维架构 > Shell

详解shell脚本[] [[]] -n -z 的含义解析

2020-05-10 04:06 1046 查看

在写脚本的时候,总是搞不懂[] [[]]的区别,这次写一个总结,把它掌握牢固

[]和test

两者是一样的,在命令行里test expr和[ expr ]的效果相同。

test的三个基本作用是判断文件、判断字符串、判断整数。支持使用 ”与或非“ 将表达式连接起来。

test中可用的比较运算符只有==和!=,两者都是用于字符串比较的,不可用于整数比较,整数比较只能使用-eq, -gt这种形式。

无论是字符串比较还是整数比较都千万不要使用大于号小于号。当然,如果你实在想用也是可以的,对于字符串比较可以使用尖括号的转义形式, 如果比较"ab"和"bc":[ ab \< bc ],结果为真,也就是返回状态为0.

[[ ]]
这是内置在shell中的一个命令,它就比刚才说的test强大的多了。支持字符串的模式匹配(使用=~操作符时甚至支持shell的正则表达 式)。逻辑组合可以不使用test的-a,-o而使用&& ||。
字符串比较时可以把右边的作为一个模式(这是右边的字符串不加双引号的情况下。如果右边的字符串加了双引号,则认为是一个文本字符串。),而不仅仅是一个字符串,比如[[ hello == hell? ]],结果为真。

  注意:使用[]和[[]]的时候不要吝啬空格,每一项两边都要有空格,[[ 1 == 2 ]]的结果为“假”,但[[ 1==2 ]]的结果为“真”!

1. 首先,尽管很相似,但是从概念上讲,二者是不同层次的东西。
"[[",是关键字,许多shell(如ash bsh)并不支持这种方式。ksh, bash(据说从2.02起引入对[[的支持)等支持。
"["是一条命令, 与test等价,大多数shell都支持。在现代的大多数sh实现中,"["与"test"是内部(builtin)命令,换句话说执行"test"/"["时不会调用/some/path/to/test这样的外部命令(如果有这样的命令的话)。

2.[[]]结构比Bash版本的[]更通用。在[[和]]之间的所有的字符都不会被文件扩展或是标记分割,但是会有参数引用和命令替换。

用[[ ... ]]测试结构比用[ ... ]更能防止脚本里的许多逻辑错误。比如说,&&,||,<和>操作符能在一个[[]]测试里通过,但在[]结构会发生错误。

3.(( ))结构扩展并计算一个算术表达式的值。如果表达式值为0,会返回1或假作为退出状态码。一个非零值的表达式返回一个0或真作为退出状态码。这个结构和先前test命令及[]结构的讨论刚好相反。

4.[ ... ]为shell命令,所以在其中的表达式应是它的命令行参数,所以串比较操作符">" 与"<"必须转义,否则就变成IO改向操作符了(请参看上面2中的例子)。在[[中"<"与">"不需转义;
由于"[["是关键字,不会做命令行扩展,因而相对的语法就稍严格些。例如
在[ ... ]中可以用引号括起操作符,因为在做命令行扩展时会去掉这些引号,而在[[ ... ]]则不允许这样做。

5.[[ ... ]]进行算术扩展,而[ ... ]不做

6.[[ ... && ... && ... ]] 和 [ ... -a ... -a ...] 不一样,[[ ]] 是逻辑短路操作,而 [ ] 不会进行逻辑短路

应用场景分析:

1、在中括号中,判断变量的值, 加不加双引号的问题?

-z 判断 变量的值,是否为空; zero = 0

  - 变量的值,为空,返回0,为true
  - 变量的值,非空,返回1,为false

-n 判断变量的值,是否为空   name = 名字
  - 变量的值,为空,返回1,为false
  - 变量的值,非空,返回0,为true
pid="123"
    [ -z "$pid" ]  单对中括号变量必须要加双引号
   [[ -z $pid ]]   双对括号,变量不用加双引号

   [ -n "$pid" ]  单对中括号,变量必须要加双引号
   [[ -z  $pid ]]  双对中括号,变量不用加双引号

2、多个条件判断,[] 和 [[]] 的区别?

2.1:[[ ]] 双对中括号,是不能使用 -a 或者 -o的参数进行比较的;

&& 并且 || 或 -a 并且 -o 或者

[[ ]] 条件判断 && 并且 || 或

[[ 5 -lt 3 || 3 -gt 6 ]] 一个条件,满足,就成立 或者的关系
[[ 5 -lt 3 || 3 -gt 6 ]] 一个条件满足,就成立 或者的关系

[[ 5 -lt 3 ]] || [[3 -gt 6 ]]
[[ 5 -lt 3 ]] || [[3 -gt 6 ]] 写在外面也可以

&& 必须两个条件同时满足,和上述一样,这里想说明的问题的是:

[[ 5 -lt 3]] -o [[ 3 -gt 6 ]] [[ 5 -lt 3 -o 3 -gt 6 ]]
[[ 5 -lt 3 -a 3 -gt 6 ]] [[ 5 -lt 3 -a 3 -gt 6 ]]
-a 和 -o就不成立了,是因为,[[]] 双对中括号,不能使用 -o和 -a的参数

直接报错:


2.2 [ ] 可以使用 -a -o的参数,但是必须在 [ ] 中括号内,判断条件,例如:

[ 5 -lt 3 -o 3 -gt 2 ] 或者条件成立
[5 -lt 3 ] -o [ 3 -gt 2] 或者条件, 这个不成立,因为必须在中括号内判断

如果想在中括号外判断两个条件,必须用&& 和 || 比较
[5 -lt 3 ] || [ 3 -gt 2]
[5 -gt 3 ] && [ 3 -gt 2] 成立

相对的,|| 和 && 不能在中括号内使用,只能在中括号外使用

3、当判断某个变量的值是否满足正则表达式的时候,必须使用[[ ]] 双对中括号


单对中括号,直接报错:


到此这篇关于详解shell脚本[] [[]] -n -z 的含义解析的文章就介绍到这了,更多相关shell [] [[]] -n -z 内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  shell [] [[]] -n -z