在bash中,[] 的作用是什么?

13

可能是重复问题:
bash:双括号、单括号、括号和花括号

查看archlinux中的rc.d cron脚本:

#!/bin/bash
. /etc/rc.conf
. /etc/rc.d/functions

name=crond
. /etc/conf.d/crond
PID=$(pidof -o %PPID /usr/sbin/crond)

case "$1" in
start)
    stat_busy "Starting $name daemon"
    [[ -z "$PID" ]] && /usr/sbin/crond $CRONDARGS &>/dev/null \
    && { add_daemon $name; stat_done; } \
    || { stat_fail; exit 1; }
    ;;

虽然我了解大部分的语法,但是这个代码真的是令人难以理解:

 [[ -z "$PID" ]]

我看到这样写:

 [ -z "$PID" ]

我在参考资料中发现[]在if语句中被使用,但我在这里看不到。非常感谢您的帮助。谢谢!

3个回答

14

左方括号 ([) 是 test 命令的别名,它执行所有测试并返回 0 表示为真,否则为其他值表示为假。"if" 语句只接受 test 命令的返回值。右方括号告诉 test 命令表达式的结束位置。双方括号 ([[) 是 bash 内置命令,可以替换对 test 的外部调用。


1
请注意,if [ expression ];if test expression; 是相同的。如果您使用 [ 而不是 test,则需要将右括号作为最后一个参数。此外,test/[ 也都内置于 bash 中。 - chepner
这里的测试是什么?-z?它是做什么的? - Andriy Drozdyuk
@drozzy test -z 用于判断作为参数传递的字符串是否为空。 - Charles Duffy
@drozzy test -z 用于测试零长度,实际上是一个空字符串。 - Mithrandir

8
单括号模拟了旧版Unix实用程序/usr/bin/test的功能。它们可以完成你要求的功能,但并非你想要的。双括号是Bash特有的改进。

http://tldp.org/LDP/abs/html/testconstructs.html#DBLBRACKETS

存在一个专门的命令叫做 [ (左方括号特殊字符)。它是test的同义词,并且出于效率原因而内置。该命令将其参数视为比较表达式或文件测试,并返回与比较结果相对应的退出状态(0表示true,1表示false)。
从版本2.02开始,Bash引入了[[...]]扩展测试命令,它以更熟悉其他语言程序员的方式执行比较。请注意,[[是一个关键字,而不是一个命令。
在[[和]]之间不进行文件名扩展或单词拆分,但存在参数扩展和命令替换。
使用[[...]]测试结构,而不是[...],可以避免脚本中的许多逻辑错误。例如,&&、||、<和>操作符在[[...]]测试中起作用,而在[...]结构中会导致错误。

+1 表示“做你要求的,而不是你想要的”。 - chepner
我不希望我的电脑猜测我的意图,而是坚持按照我说的话去执行。 :-) - Mithrandir
@Mithrandir...但是如果它以一种不太可能是你实际想要的方式来解释你说的话,那就是一个问题--这就是test所做的,而[[ ]]不仅可预测,而且更有可能是正确的。 - Charles Duffy
2
一个很好的解释,虽然ABS在其他方面充满错误(我们经常帮助那些按照其建议犯错的人在#bash),这可能会引导人们到那里——也许需要在http://mywiki.wooledge.org/BashGuide/TestsAndConditionals上添加“更多信息请参见”的链接? - Charles Duffy
@CharlesDuffy 当然,你是对的,[[更容易使用,但是test在我这里做得非常好(比我愿意承认的时间更长),但是必须小心使用以防止出现意外行为。 - Mithrandir
双括号在ksh和zsh中也被支持,因此它们不是Bash特有的。 - Dennis Williamson

0

来自 this 手册:

方括号用于返回表达式的二进制结果:[[ ]]

[[ expression ]]

根据条件表达式的评估返回0或1的状态。在[[]]之间的单词不执行单词分割和文件名扩展。执行波浪线扩展、参数和变量扩展、算术扩展、命令替换、进程替换和引号删除。

如果expression1的值足以确定整个条件表达式的返回值,则&&||命令不执行expression2。


1
"二进制结果"? 也许是,但"布尔结果"可能更精确。 - Dennis Williamson

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接