我深信这是一种教育法上的广泛错误, 那就是告诉大家说:
if [ condition ]
then
...
fi
这是bash中条件语句的"语法".
任何人, 或者说几乎任何人, 都会在这种描述下自然地认为: [ 和 ] 是这种语法结构本身的一部分, 并且, 老老实实地在自己的脚本中总是这样使用if 语句, 如果你总是在判断字符串是否相等, 或文件的各种属性, 这么做倒是没错, 只不过你可能会这样犯错:(下文都假设$1内容为-a)
if ["$1" = "-a" ]
或
if [ "$1 = "-a"]
毕竟, 很多其它语言中, 特殊符号如()、{}做分隔符时, 可以与被分隔内容亲密无间. 而bash会来答复你的这种写法:
[-a: command not found
bash: [: missing `]'
我相信, 以上这种心理模型造成的失败后果十分严重, bash的错误信息显示出它内部并不这样看待if 条件语句的结构.
上面的模型同样不能解释下面的合法bash 命令:
[ "$1" = "-a" ]
仅仅这本身就是一个合法的命令, 没有if、then、fi这些东西,当然, 下面这样的也合法
[ "$1" = "-a" ] && echo yes
你如何解释这些烂事? 当然你可以自圆其说地不断对上面的if进行补充, 呃, [ .. ] 这种结构就是这么特别, 你必需在[之后有至少一个空格, 并且在]之前也至少有一个空格, 同时[..] 结构还可以单独出现, 就象上面这样, 另外... 这样的解释简直是自欺欺人, 我敢保证企图对自己这样解释的人根本自己就在怀疑这种说法, 因为你根本不知道这个结构还有其它什么怪诞诡秘之处何时会突然跳出来让你大吃一惊. 我承认,我自己也曾经经历过这样的想法.
为了彻底批判这种错误概念, 容我再举一例:
if ps ax | grep oracle > /dev/null 2>&1 ; then
...
fi
首先, 这是合法的, 它的目的是想知道进程列表中有没有与oracle相关的东西, 当然, 如果你够牛, 就能看出这种做法有另外的问题. 但这不是我想说的重点.
我想说的是, 你前面被教导的这种if 语句的语法模型, 如何解释这个, [ 与 ] 又不见了, 并且还出现了管道, 普通的管道我们都见过, 但它能安全地出现在if 语句中吗, 并且, 让你感觉熟悉和安全的[ 和 ]又不见了.
