I'm reading JSON in a shell script using JQ. Here, I'm unable to interpret the variables $HOME, $HOST, $PEMFILE in my shell script on the fly.
JSON File:
{
"script": {
"install": "${HOME}/lib/install.sh $HOST $PEMFILE",
"Setup": "${HOME}/lib/setup.sh $HOST $PEMFILE $VAR1 $VAR2"
}
}
Shell Script:
#!/bin/bash
examplefile="../lib/example.json"
HOST=ec2-..-...-...-...us-west-2.compute.amazonaws.com
PEMFILE=${HOME}/test.pem
installScript=($(jq '.script.install' $examplefile))
bash "$installScript"
Is there a way I can interpret these variables on the fly without modifying the JSON?
P.S I don't want to use eval.
Specific solution
Here's a jq solution to the stated problem, though it will only work for "global" environment variables.
If your jq does not already have
walk/1
, then please either upgrade your jq or snarf the def from https://github.com/stedolan/jq/blob/master/src/builtin.jqThe solution above is a bit brittle but it could easily be robustified or generalized, as shown in the next section.
General solution
I've been hitting this on and off for years. I think I've finally got a decent pure-bash solution: uses regex matching and indirect parameter substitution
Output
The magic is:
the regular expression, where I capture both
$VAR
andVAR
, andthe parameter substitution, where I search for the string
"$VAR"
and replace it with the indirect variable expansion${!VAR}
Here is a solution using env and gsub to perform the replacement.
Note that
env
requires the variables to be passed as environment variables as opposed to shell variables.Sample Output
Try it online!
It is easy using gnu utility
envsubst
: