我已经破解了很多 shell 脚本,有时最简单的事情也让我感到困惑。今天我遇到了一个广泛使用:
(冒号)bash 内置函数的脚本。
这文档看起来很简单:
: (a colon) : [arguments]
除了扩展参数和执行重定向之外,不执行任何操作。返回状态为零。
然而我以前只在 shell 扩展的演示中看到过它的使用。我遇到的脚本中的用例广泛使用了这种结构:
if [ -f ${file} ]; then
grep some_string ${file} >> otherfile || :
grep other_string ${file} >> otherfile || :
fi
实际上有数百个 grep,但它们只是更多相同。除了上面的简单结构之外,不存在输入/输出重定向。稍后在脚本中不会检查返回值。
我将其视为一个无用的结构,即“或什么都不做”。用“或什么也不做”结束这些 grep 可以达到什么目的?在什么情况下,这种构造会导致与简单地|| :
从所有实例中删除 不同的结果?
答案1
内置命令:
对于 Bash“分配默认值”shell 扩展也很有用,其中扩展通常仅用于副作用,而扩展的值会被丢弃:
# assign FOO=bar iff FOO is unset or empty
: "${FOO:=bar}"
答案2
看来:
您的脚本中的 s 正在用来代替true
.如果grep
在文件中没有找到匹配项,它将返回一个非零退出代码;正如 jw013 在评论中提到的,如果errexit
设置了(可能是在 shebang 行),如果任何一个s 找不到匹配项-e
,脚本将退出。grep
显然,这不是作者想要的,因此他添加了|| :
使该特定复合命令的退出状态始终为零的内容,就像更常见的(根据我的经验)|| true
/ || /bin/true
。
答案3
答案4
我翻出了一本旧参考资料:《UNIX 编程环境》(c) 1984 年,作者:Kernighan 和 Pike。
第 147 页(Shell 编程)是这样说的:
“:”是一个 shell 内置命令,除了计算其参数并返回“true”之外什么也不做。相反,[参考脚本示例],我们可以使用真的,它仅返回真实的退出状态。 (还有一个错误的命令。)但是 ':' 比 true 更有效因为它不执行来自文件系统的命令。 [斜体/强调是我的。]