In-Memory Here Doc
When shell encounters any of these syntaxes:
  • n<< delimiter or n<<- delimiter
  • n<< 'delimiter'or n<<- 'delimiter'
  • n<< "delimiter"or n<<- "delimiter"
where n is a number (0-9), it starts creating a multi-line buffer to be sent to file descriptor n.
When you combine that with the exec builtin, you can buffer input to a file descriptor. For example:
1
1 #!/bin/sh
2
2 exec 3<< EOF
3
3 Buffered data
4
4 EOF
5
5 cat <&3
Copied!
Produces:
1
Buffered data
Copied!
The above example uses file descriptor 3 because 0-2 are reserved in POSIX for stdin, stdout, and stderr respectively.
An in-memory here-doc can be combined with the indented here-doc.
1
1 #!/bin/sh
2
2 if : true; then
3
3 exec 3<<- EOF
4
4 Buffered line 1
5
5 \ Buffered line 2
6
6 EOF
7
7 awk 'sub(/^\\\t/,"\t")||1' <&3
8
8 fi
Copied!
You can collect the buffered data inside a sub-shell to store it in a variable.
1
1 #!/bin/sh
2
2 exec 3<< EOF
3
3 Buffered data
4
4 EOF
5
5 data=$( cat <&3 )
6
6 echo "$data"
Copied!
When using the variable to which the data is assigned, quoting it prevents word-splitting from being performed on expansion.
Copy link