planetp
planetp

Reputation: 16075

What does @<(cat <<- EOF do in Bash?

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?

Upvotes: 3

Views: 5965

Answers (1)

KamilCuk
KamilCuk

Reputation: 141060

<(...) 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.

Upvotes: 9

Related Questions