我在 Bash 脚本中偶然发现了一些奇怪的 heredoc 用法。一个简化的例子是这样的:
do_stuff() {
notify @<(cat <<- EOF
{
"key": "value",
<more JSON data>
}
EOF
)
}
零件有什么@<(cat <<- EOF
作用?它与普通的heredoc有什么不同?
我在 Bash 脚本中偶然发现了一些奇怪的 heredoc 用法。一个简化的例子是这样的:
do_stuff() {
notify @<(cat <<- EOF
{
"key": "value",
<more JSON data>
}
EOF
)
}
零件有什么@<(cat <<- EOF
作用?它与普通的heredoc有什么不同?
<(...)
是一个进程替换。Bash 在某个目录中创建一个 fifo 并在其中运行命令<(...)
并将表达式替换为 fifo 名称。进程替换具有(奇怪的)生命周期规则,但它们通常在命令或行结束之前有效。例如:
$ cmd=<(echo 123); echo cmd=$cmd; cat $cmd
cmd=/dev/fd/63
123
<<-EOF
是这里的文件。如果在分隔符-
前面有,则以下行的前导选项卡(包括带有分隔符的行)将被忽略。(注意:stackoverflow 不保留标签)。
$ echo -e '
cat <<EOF
\tblabla
EOF
cat <<-EOF
\t\t\t\t\tblabla
\t\t\t\t\t\t\t\t\t\t\t\t\tEOF
' > file.sh
$ bash ./file.sh
blabla
blabla
notify @<(...)
只是将里面的部分替换<(...)
为 some/dev/fd/<number>
并执行notify @/dev/fd/<number>
。可能@
用于notify
进程以指示它应该从文件中读取,参数的其余部分是文件名。然后cat
将输出绑定到/dev/fd/<number>
使用进程替换创建的 fifo 的进程,该进程在标准输入上cat
接收此处的文档内容。将标准输入输出到输出,然后我猜会读取 fifo 并接收字符。{ <more json data> }
cat
notify