2

I'm implementing a template renderer in shell script. The template variables are represented in a template by @VAR_NAME@ and their values are defined in a separate shell script.

Sample code:

# template variables values
CONTACT_EMAIL="myemail"
CONTACT_NAME="myname"
VARS="CONTACT_EMAIL CONTACT_NAME"

TEMPLATE_FILEPATH="mytemplate.txt"

# template renderer
set -x
SEDARGS=
for VAR in $VARS; do
     SEDARGS+=" -e \"s,@$VAR@,${!VAR},\""
done
sed -r $SEDARGS $TEMPLATE_FILEPATH

sed command executed by shell and printed by it because of "set -x":

+ sed -r -e '"s,@CONTACT_EMAIL@,myemail,"' -e '"s,@CONTACT_NAME@,myname,"' mytemplate.txt 

sed output:

sed: -e expression #1, char 1: unknown command: `"'

I know the single quotes around each sed expression are causing this non-intuitive error message, but I do not know why they are added.

What is wrong?

Alan Evangelista
  • 2,888
  • 6
  • 35
  • 45
  • 1
    possible duplicate of [Is it possible to escape regex metacharacters reliably with sed](http://stackoverflow.com/questions/29613304/is-it-possible-to-escape-regex-metacharacters-reliably-with-sed) ... I mean *possible*, and I hope the link helps. – hek2mgl Jun 18 '15 at 21:10
  • 1
    `SEDARGS+=" -e 's,@$VAR@,${!VAR},' "` might work. Interesting idea! good luck. – shellter Jun 18 '15 at 21:12

2 Answers2

1

You have embedded quotes inside your SEDARGS variable. These are NOT removed when the command is executed. To remove them, you need to call the interpreter again, which you can do using eval. For example:

eval sed -r $SEDARGS $TEMPLATE_FILEPATH

You may need to play around that some more (adding quotes, etc.).

rghome
  • 8,529
  • 8
  • 43
  • 62
  • That worked, thanks! This is very tricky. I assume that the Linux shell first parses the quotes and then performs variable substitution? – Alan Evangelista Jun 18 '15 at 21:27
  • Yes. It has to do it in that order, otherwise the single quotes wouldn't stop the variable expansion. – rghome Jun 18 '15 at 21:32
0

The single quotes aren't part of the actual arguments. They get added by your shell for the output caused by set -x only.

Why would the shell do that? So that you can use that output to re-run exactly what was executed during the script execution. As you correctly noticed, they are needed to protect the " that came from SEDARGS content (i.e., the inner ones, in your script escaped as \").

das-g
  • 9,718
  • 4
  • 38
  • 80