Reputation: 24160
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.
Upvotes: 6
Views: 21068
Reputation: 2800
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
Upvotes: 1
Reputation: 70872
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.
Upvotes: 2
Reputation: 189648
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.
Upvotes: 7