You can avoid a useless use of cat and handle mismatched quotes better with this:
$ read -r -d '' VAR <<'EOF'
abc'asdf"
$(dont-execute-this)
foo"bar"''
EOF
If you don't quote the variable when you echo it, newlines are lost. Quoting it preserves them:
$ echo "$VAR"
abc'asdf"
$(dont-execute-this)
foo"bar"''
If you want to use indentation for readability in the source code, use a dash after the less-thans. The indentation must be done using only tabs (no spaces).
$ read -r -d '' VAR <<-'EOF'
abc'asdf"
$(dont-execute-this)
foo"bar"''
EOF
$ echo "$VAR"
abc'asdf"
$(dont-execute-this)
foo"bar"''
If, instead, you want to preserve the tabs in the contents of the resulting variable, you need to remove tab from IFS. The terminal marker for the here doc (EOF) must not be indented.
$ IFS='' read -r -d '' VAR <<'EOF'
abc'asdf"
$(dont-execute-this)
foo"bar"''
EOF
$ echo "$VAR"
abc'asdf"
$(dont-execute-this)
foo"bar"''
Tabs can be inserted at the command line by pressing Ctrl-V Tab. If you are using an editor, depending on which one, that may also work or you may have to turn off the feature that automatically converts tabs to spaces.
In read -r -d '', the options are:
-r to accept backslashes literally instead of using them to escape any characters
-d sets the first character of the following argument as the delimiter between records (lines), instead of the default which is newline. In the example, I'm setting the delimiter to a null string, so that the whole string passed to read will be read as one record.
'EOF', with escaped linebreaks with` in the content: if the second line hascd` command, I get back: ".sh: line X: cd: command not found"; but if I double-quote"EOF"; then bash variables${A}do not get preserved as strings (they get expanded); but then, line-breaks are preserved - and, I don't have a problem running a command withcdin second line (and both 'EOF' and "EOF" seem to play well also witheval, for running a set of commands stored in a string variable). Cheers!"EOF"variable, if called viaeval $VAR, will cause all of the rest of the script to be commented, as here $VAR will be seen as a single line; to be able to use bash#comments in multiline script, double-quote also variable in theeval call:eval "$VAR"`.evalith this methods, but did not track it down since it was part of some package whichevals some variables defined in it's config file. Error message was:/usr/lib/network/network: eval: line 153: syntax error: unexpected end of file. I just switched to another solution.