I'm trying to create a JSON in BASH where one of the fields is based on the result of an earlier command

BIN=$(cat next_entry)
OUTDIR="/tmp/cpupower/${BIN}"
echo $OUTDIR
JSON="'"'{"hostname": "localhost", "outdir": "${OUTDIR}", "port": 20400, "size": 100000}'"'"
echo $JSON

The above script when executed, returns:

/tmp/cpupower/0
, port: 20400, size: 100000}': /tmp/cpupower/0

How can I properly substitute variables inside these multi-quoted strings?

share|improve this question
up vote 3 down vote accepted
JSON=\''{"hostname": "localhost", "outdir": "'"$OUTDIR"'", "port": 20400, "size": 100000}'\'

That is get out of the single quotes for the expansion of $OUTDIR. We did put that expansion inside double-quotes for good measure even though for a scalar variable assignment it's not strictly necessary.

When you're passing the $JSON variable to echo, quotes are necessary though to disable the split+glob operator. It's also best to avoid echo for arbitrary data:

printf '%s\n' "$JSON"
share|improve this answer
    
Cool. This works! Could you perhaps explain a little more on why this works? What is the significance of the first \'. I don't believe I've seen that on some of the examples I've seen on SO/unix.stackexchange. – Guru Prasad Sep 27 '16 at 14:29
    
Backslash before ' tells the shell to treat ' as any ordinary character, instead of interpreting it as a string delimiter. The backslash can be used in front of a few other characters. For example, \\ will represent the \ character itself and \" means the " character literary. See for example the \n in above printf argument, where printf interprets \n as the line-feed character. – Rein Sep 30 '16 at 16:47

Stéphane's answer is great, and upvoted. Here's just a tip; instead of doing

BIN=$(cat next_entry)

You can do:

BIN=$(<next_entry)

And thus save spawning an extra process. Read more here.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.