bashio-redirectionheredocprocess-substitution

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?


Solution

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