6

I have utility which accept JSON as argument. How to escape json correctly to pass to the utility? Example:

ip="127.0.0.1"
action='{\"server_ip\":\"$ip\",\"action\":\"stop\"}'
./fix-utility -e $action

But JSON is not getting escaped correctly.

3 Answers 3

7

If you want interpolation of e.g. $ip inside the string, you need to use double quotes. Double quotes in the value need backslash escaping.

ip="127.0.0.1"
action="{\"server_ip\":\"$ip\",\"action\":\"stop\"}"
./fix-utility -e "$action"

Actually, I would advise against storing the action in a variable, unless your example omits something crucial which makes it necessary.

Sign up to request clarification or add additional context in comments.

2 Comments

Can you please elaborate why I should not store action in variable ?
In this limited example, at least, it is a superfluous complication, especially if you ara not completely certain of quoting and evaluation rules.
2

Double quotes and single quotes is not considered same by bash interpreter: While double-quote let bash expand contained variables, single quote don't. Try simply:

echo "$BASH_VERSION"
4.1.5(1)-release
echo '$BASH_VERSION'
$BASH_VERSION

At all, there is a nice reusable bash way:

declare -A jsonVar
toJsonString() {
    local string='{'
    for var in ${!jsonVar[*]} ;do
        string+="\"$var\":\"${jsonVar[$var]}\","
      done
    echo ${string%,}"}"
}

jsonVar[action]=stop
jsonVar[server_ip]=127.0.1.2

toJsonString
{"action":"stop","server_ip":"127.0.1.2"}

And finally:

./fix-utility -e "$(toJsonString)"

This could be improved if specials chars like " double-quotes have to be part of some strings.

Comments

1

Updating this old question with newer tools. This solution relies on python's jq since it's a great tool for manipulating JSON files and strings.

Using the native bash string concatenation, one can do without having to escape anything manually and rely on jq to perform all the escaping.

# let's say I have need to include a variable within a string containing characters to escape
> my_string='a'"b"'c'
> echo -e "$my_string"
abc

> my_string='!(){'"$variable"'}[]'
> echo -e "$my_string"
!(){my_value_here}[]

# in effect, I'm concatenating these 3 strings together:
'!(){'
"$variable"
'}[]'

The single quotes prevent interpretation by bash, the double quote allow interpretation of the variable by bash.

Now, to escape, I would advise using python's jq program (pip install jq).

> ip="127.0.0.1"
> action='{"action":"stop","server_ip":"'"$ip"'"}'
> echo -e "${action}" | jq -cM '. | @text '
"'{\"action\":\"stop\",\"server_ip\":\"127.0.0.1\"}'"

For context, here are the versions of bash and jq that I'm using:

> bash --version
GNU bash, version 3.2.57(1)-release (x86_64-apple-darwin18)
Copyright (C) 2007 Free Software Foundation, Inc.
> jq --version
jq-1.6

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.