@<(cat <<- EOF 在 Bash 中做什么?

pla*_*etp 3 bash heredoc io-redirection process-substitution

我在 Bash 脚本中偶然发现了一些奇怪的 heredoc 用法。一个简化的例子是这样的:

do_stuff() {
      notify @<(cat <<- EOF
  {
      "key": "value",
       <more JSON data>
  }
  EOF
               )
  }
Run Code Online (Sandbox Code Playgroud)

什么是@<(cat <<- EOF部分呢?它与常规的heredoc有什么不同?

Kam*_*Cuk 5

<(...)是一个过程替换。Bash 在某个目录中创建一个 fifo 并在其中运行命令<(...)并用 fifo 名称替换表达式。进程替换具有(奇怪的)生命周期规则,但它们通常在命令或行结束之前一直有效。例如:

$ cmd=<(echo 123); echo cmd=$cmd; cat $cmd
cmd=/dev/fd/63
123
Run Code Online (Sandbox Code Playgroud)

<<-EOF是一个here 文档。如果有-分隔符的前面,那么包括带分隔符的行在内的后续行上的前导选项卡将被忽略。(注意: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
Run Code Online (Sandbox Code Playgroud)

notify @<(...)只是将<(...)里面的部分替换为 some/dev/fd/<number>并执行notify @/dev/fd/<number>. 可能@用于notify进程以指示它应该从文件中读取,参数的其余部分是文件名。然后cat将输出绑定到/dev/fd/<number>使用进程替换创建的 fifo 的进程,该cat进程接收{ <more json data> }标准输入上的 here 文档内容。cat输出标准输入输出,然后我猜notify读取fifo并接收字符。