How to assign a heredoc value to a variable in Bash?
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.
Use $() to assign the output of cat
to your variable like this:
VAR=$(cat <<'END_HEREDOC'abc'asdf"$(dont-execute-this)foo"bar"''END_HEREDOC)# this will echo variable with new lines intactecho "$VAR"# this will echo variable without new lines (changed to space character)echo $VAR
Making sure to delimit starting END_HEREDOC with single-quotes.
Note that ending heredoc delimiter END_HEREDOC
must be alone on the line (hence ending parenthesis is on the next line).
Thanks to @ephemient
for the answer.
this is variation of Dennis method, looks more elegant in the scripts.
function definition:
define(){ IFS='\n' read -r -d '' ${1} || true; }
usage:
define VAR <<'EOF'abc'asdf"$(dont-execute-this)foo"bar"''EOFecho "$VAR"
enjoy
p.s. made a 'read loop' version for shells that do not support read -d
. should work with set -eu
and unpaired backticks, but not tested very well:
define(){ o=; while IFS="\n" read -r a; do o="$o$a"''; done; eval "$1=\$o"; }