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

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

    []和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 内容请搜索lingkb以前的文章或继续浏览下面的相关文章希望大家以后多多支持lingkb!