0

How can I externalize the template part of a "heredoc"?

I have a bash script that uses a "heredoc" to write data to a file:

foo=bar

data=$(cat <<EOF
foo: $foo
EOF
)

echo $data

When executing this script, I see the expected foo: bar.

Now, I would like to pull out the template part from the script to support multiple output formats using different template files. For example, a template.properties file containing just:

foo: $foo

For this reason I modified the script:

foo=bar

template=$(cat template.properties)

data=$(cat <<EOF
$template
EOF
)

echo $data

The problem I am having is that the $foo variable never gets evaluated, i.e. the above code prints out foo: $foo instead of the desired foo: bar.

matsev
  • 32,104
  • 16
  • 121
  • 156

1 Answers1

1

You don't need the cat (kill the cat!) and you don't need the here-doc either. Unfortunately you do need eval:

foo=bar

read -r template < template.properties

eval data="\"$template\""

echo $data

eval is often referred to as "evil" because it can pose a security risk. Any malicious command, or error, could be inserted and executed. It is usually best to avoid embedding code like this.

Why not write the template so you just source it? For example, make the template:

data=$foo

and your code:

foo=bar

source template.properties
echo $data  
cdarke
  • 42,728
  • 8
  • 80
  • 84
  • Thanks. Sourcing the template is a good idea, but I also need to support other data formats such as JSON, e.g. `{"foo": "$foo"}`. – matsev Sep 20 '16 at 07:16
  • You might be better off using something like `python` which comes bundled with a JSON module and supports many other data formats as well. – cdarke Sep 20 '16 at 08:21