I've stumbled upon some weird heredoc usage in a Bash script. A simplified example goes like this:
do_stuff() {
notify @<(cat <<- EOF
{
"key": "value",
<more JSON data>
}
EOF
)
}
What does the @<(cat <<- EOF
part do? How is it different from a regular heredoc?
<(...)
is a process substitution. Bash creates a fifo in some directory and run the command inside <(...)
and substitutes the expression with the fifo name. Process substitutions have (strange) lifetime rules, but they are usually valid till the end of command or line. For example:
$ cmd=<(echo 123); echo cmd=$cmd; cat $cmd
cmd=/dev/fd/63
123
<<-EOF
is a here document. If there is -
in front of the delimeter then leading tabs on following lines including the line with delimeter are ignored. (Note: stackoverflow doesn't preserve tabs).
$ 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 @<(...)
just substitutes the <(...)
part inside for some /dev/fd/<number>
and executes notify @/dev/fd/<number>
. Probably the @
is used for notify
process to indicate it should read from file and the rest of the argument is the filename. Then the cat
process that has tied output to /dev/fd/<number>
fifo created with process substitution, the cat
process receives the here document content { <more json data> }
on standard input. cat
outputs standard input to output and then I guess notify
reads the fifo and receives the characters.