我最近在创建函数的上下文中遇到了这种非常简洁的语法,该bash
函数可以接受来自 STDIN 的参数或流(即可以通过管道传输到)。从表面上看,我了解这里发生了什么,但我想更多地解释一下它是如何工作的实际机制。
这是语法(根据标题):${1:-$(</dev/stdin)}
在上下文中,可以将其用作:
log(){
echo -e >&1 "INFO: ${1:-$(</dev/stdin)}"
}
允许以下用法:
$ log foo
INFO: foo
或者,您也可以这样做
mv -v foo.ext bar.ext | log
INFO: renamed 'foo.ext' -> 'bar.ext'
这很棒,因为它是我见过的使用函数同时启用参数和管道功能的最简洁的方法bash
(不幸的是,我忘记了我现在在哪里遇到它)。
现在,我理解(或认为我理解),这里发生的大部分事情至少是表面上的,但我希望能有更深入的理解。以下是我对它的解释,然后是我剩下的问题:
${1:-$(</dev/stdin)}
${1}
显然是函数接受的默认参数${1:-x}
'x'
如果$1
为空(或未设置?) ,则为字符串的变量/大括号扩展“回退” 。在这种情况下,回退到 STDIN 过程子。$()
显然是进程命令替换- 最后,
</dev/stdin
显然是来自标准输入的重定向,它允许管道工作。
这实质上是说如果$1
没有由参数填充,则回退到使用 STDIN——我在概念上很满意。
所以这是我的问题:
- 我从未在
进程<
命令替换中看到重定向( ),而在它之前没有实际命令(例如)。那么,当进程命令替换接收到重定向而没有其他命令可以调用时,实际发生了什么(本质) ?$(cat < somefile.ext)
- 为什么有必要将 STDIN 重定向包装在
进程命令替换中?(实际上,当我写这篇文章时,我突然想到我没有测试过它,但我会保持简单)。 - 这安全吗?我已经将它与多行标准输入一起使用,到目前为止它还没有损坏。这可能会落在哪里(如果有的话?)。