How do I pass literal variable templates to jq from within Make?

Viewed 1065

I'm trying to use jq within a Makefile to generate a json file. Here is a sample Makefile

foo.json:
    jq -n --arg x "bar" '{"foo": "$$x"}' > foo.json
    @cat foo.json
    @rm foo.json

When I run this with GNU Make v4.3 and jq v1.6 I get the following

make
jq -n --arg x "bar" '{"foo": "$x"}' > foo.json
{
  "foo": "$x"
}

Notice that $x shows up literally and doesn't get interpolated by jq. How do I achieve the following...

make
jq -n --arg x "bar" '{"foo": "$x"}' > foo.json
{
  "foo": "bar"
}
3 Answers

You simply don't need to wrap your variable in quotes:

jq -n --arg x "bar" '{foo: $x}'

Or use string interpolation:

jq -n --arg x "bar" '{foo: "\($x)"}'

Thanks to @customcommander for the tip. The answer was not quoting the dollar signs or the var at all. Updated Makefile confirmed working...

$ cat Makefile 
foo.json:
    jq -n --arg x $X '{"foo": $$x}' > foo.json
    @cat foo.json
    @rm foo.json

$ X=123 make
jq -n --arg x 123 '{"foo": $x}' > foo.json
{
  "foo": "123"
}
$ X=456 make
jq -n --arg x 456 '{"foo": $x}' > foo.json
{
  "foo": "456"
}

I ended up avoiding jq --arg entirely and went with a simpler approach.

Example Makefile:

# the arg to pass to jq
SOME_VAR?=my-var

foo.json:
    jq -n  '{"foo": "'"$(SOME_VAR)"'"}' > foo.json
    @cat foo.json
    @rm foo.json

Example usage:

$ make foo.json
jq -n  '{"foo": "'"my-var"'"}' > foo.json
{
  "foo": "my-var"
}

Quoted variables work too:

$ SOME_VAR="hi" make foo.json
jq -n  '{"foo": "'"hi"'"}' > foo.json
{
  "foo": "hi"
}
Related