Using variables inside a bash heredoc Using variables inside a bash heredoc bash bash

Using variables inside a bash heredoc


In answer to your first question, there's no parameter substitution because you've put the delimiter in quotes - the bash manual says:

The format of here-documents is:

      <<[-]word              here-document      delimiter

No parameter expansion, command substitution, arithmetic expansion, or pathname expansion is performed on word. If any characters in word are quoted, the delimiter is the result of quote removal on word, and the lines in the here-document are not expanded. If word is unquoted, all lines of the here-document are subjected to parameter expansion, command substitution, and arithmetic expansion. [...]

If you change your first example to use <<EOF instead of << "EOF" you'll find that it works.

In your second example, the shell invokes sudo only with the parameter cat, and the redirection applies to the output of sudo cat as the original user. It'll work if you try:

sudo sh -c "cat > /path/to/outfile" <<EOTmy text...EOT


Don't use quotes with <<EOF:

var=$1sudo tee "/path/to/outfile" > /dev/null <<EOFSome text that contains my $varEOF

Variable expansion is the default behavior inside of here-docs. You disable that behavior by quoting the label (with single or double quotes).


As a late corolloary to the earlier answers here, you probably end up in situations where you want some but not all variables to be interpolated. You can solve that by using backslashes to escape dollar signs and backticks; or you can put the static text in a variable.

Name='Rich Ba$tard'dough='$$$dollars$$$'cat <<____HERE$Name, you can win a lot of $dough this week!Notice that \`backticks' need escaping if you wantliteral text, not `pwd`, just like in variables like\$HOME (current value: $HOME)____HERE

Demo: https://ideone.com/rMF2XA

Note that any of the quoting mechanisms -- \____HERE or "____HERE" or '____HERE' -- will disable all variable interpolation, and turn the here-document into a piece of literal text.

A common task is to combine local variables with script which should be evaluated by a different shell, programming language, or remote host.

local=$(uname)ssh -t remote <<:    echo "$local is the value from the host which ran the ssh command"    # Prevent here doc from expanding locally; remote won't see backslash    remote=\$(uname)    # Same here    echo "\$remote is the value from the host we ssh:ed to":