> For the complete documentation index, see [llms.txt](https://freebsdfrau.gitbook.io/serious-shell-programming/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://freebsdfrau.gitbook.io/serious-shell-programming/basics/here-documents/in-memory-here-doc.md).

# 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 #!/bin/sh
2 exec 3<< EOF
3 Buffered data
4 EOF
5 cat <&3
```

Produces:

```
Buffered data
```

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 #!/bin/sh
2 if : true; then
3     exec 3<<- EOF
4     Buffered line 1
5     \    Buffered line 2
6     EOF
7     awk 'sub(/^\\\t/,"\t")||1' <&3
8 fi
```

You can collect the buffered data inside a sub-shell to store it in a variable.

```
1 #!/bin/sh
2 exec 3<< EOF
3 Buffered data
4 EOF
5 data=$( cat <&3 )
6 echo "$data"
```

When using the variable to which the data is assigned, quoting it prevents word-splitting from being performed on expansion.
