Cal*_*leb 49 shell-script shell-builtin
我已经破解了很多 shell 脚本,有时最简单的事情让我感到困惑。今天我遇到了一个广泛使用:(冒号)bash 内置的脚本。
该文档似乎很简单:
Run Code Online (Sandbox Code Playgroud): (a colon) : [arguments]除了扩展参数和执行重定向之外,什么都不做。返回状态为零。
但是,我以前只在 shell 扩展的演示中看到过这个。我遇到的脚本中的用例广泛使用了这种结构:
if [ -f ${file} ]; then
grep some_string ${file} >> otherfile || :
grep other_string ${file} >> otherfile || :
fi
Run Code Online (Sandbox Code Playgroud)
实际上有数百个 grep,但它们只是更多相同。除了上面的简单结构之外,不存在输入/输出重定向。稍后在脚本中不会检查返回值。
我正在阅读这是一个无用的结构,上面写着“或什么都不做”。用“或什么都不做”来结束这些 grep 的目的是什么?在什么情况下,这个构造会导致与简单地|| :从所有实例中删除不同的结果?
Jon*_*oni 47
的:内置也与打击“分配默认值”壳膨胀,其中所述膨胀通常仅用于副作用和膨胀值被扔掉有用:
# assign FOO=bar iff FOO is unset or empty
: "${FOO:=bar}"
Run Code Online (Sandbox Code Playgroud)
Kev*_*vin 31
看来:脚本中的s 正在代替true. 如果grep在文件中没有找到匹配项,它将返回一个非零退出代码;正如 jw013 在评论中提到的,如果errexit设置了,可能是-e在 shebang 行上,如果任何greps 未能找到匹配项,脚本将退出。显然,这不是作者想要的,所以 (s) 他添加|| :了使该特定复合命令的退出状态始终为零,就像更常见的(根据我的经验)|| true/ || /bin/true。
Bru*_*ger 24
我能想到我过去用过的两个地方:。
while :
do
shell commands
some exit condition
done
Run Code Online (Sandbox Code Playgroud)
那是一个永远的循环。
function doSomethingStub {
:
}
Run Code Online (Sandbox Code Playgroud)
放入存根函数,只是为了获得正确的顶级控制流。
我在过去见过的一种用法:#!/bin/sh您会看到一条:线,而不是一条(或其他任何)线。一些较旧的 Real Unix 内核或 Real Unix shell 会使用它来表示“我是一个 shell 脚本,让 sh 运行我”。我记得这正是 csh 作为通用交互式 shell 取得进展的时候。请参阅:http : //www.faqs.org/faqs/unix-faq/faq/part3/section-16.html
小智 18
我翻出了一个旧的参考资料:Kernighan 和 Pike 于 1984 年出版的“The UNIX Programming Environment”(c)。
第 147 页(Shell Programming)说:
":" 是一个 shell 内置命令,它除了计算它的参数并返回 "true" 之外什么都不做。相反[参考脚本示例],我们可以使用true,它只返回一个真正的退出状态。(还有一个false命令。)但是 ':' 比 true 更有效率,因为它不执行来自文件系统的命令。[斜体/强调是我的。]
Col*_*lin 13
":" 便于调试。
DEBUGLOG=": debugfunction"
statement
statement
$DEBUGLOG arg1 arg2 ...
statement
statement
Run Code Online (Sandbox Code Playgroud)
正常运行时,调试函数永远不会执行,所以 sh 只是跳过 noop(尽管变量和通配符被扩展)。如果需要更深入的调试,请从变量中删除 noop,并使用所需的任何参数调用 debugfunction。
另一个方便的用途是作为块注释,这是 shell 语法中缺少的功能。
: << COMMENT
all --statements --in --here
are now -a here document which are
passed to --the noop
COMMENT
Run Code Online (Sandbox Code Playgroud)
Kei*_*son 10
我似乎记得早期版本的 shell 没有注释语法。以:(可能是实际的可执行文件,类似于/bin/true)开头的行将是最好的选择。
这是古代Thompson shell的手册页(没有关系);没有提到任何注释语法。