Bash variable substitution in a JSON string

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"

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.


If you ended up here trying to use AWS commands, @Stéphane Chazelas's answer almost works. In here, the initial escaped quotes (\') are not necessary, they actualy break the command.

IP=$(curl ipecho.net/plain ; echo)

aws ec2 authorize-security-group-ingress --group-id sg-**************** \
    --ip-permissions '[{"IpProtocol": "tcp", "FromPort": 15000, "ToPort": 15000, "IpRanges": [{"CidrIp": "'"$IP/32"'", "Description": "Service A"}]}]'

^ This works just fine