Reputation: 7407
I need to catch an error when lifting a service. The response can be null
, a string error message like
error services-migration/foobar: Not found: services-migration/foobar
or a valid JSON when everything is fine. I was wondering if there is a way with jq
to simply check if the provided string is a valid JSON. I could ofc check the string for some keywords like error
f.e., but I'm looking for a more robust option, where eg. I get a true/false
or 1/0
from jq.
I was looking through the docs of jq
and also some questions here on SO but everything was about finding and picking out key-values from a JSON, but nothing about simply validating a string.
UPDATE:
I've got this:
result=$(some command)
from which the result is the string error services-migration/foobar: Not found: services-migration/foobar
And then the if statement:
if jq -e . >/dev/null 2>&1 <<<"$result"; then
echo "it catches it"
else
echo "it doesn't catch it"
fi
And it always ends up in the else
clause.
Upvotes: 66
Views: 86957
Reputation: 5093
For a variable content like for a line, that's been working for me
echo "$my_potential_json"|jq empty > /dev/null 2>&1
if [ $? -eq 0 ]; then
echo "found valid json:$my_potential_json"
do_whatever....
Upvotes: 3
Reputation: 1335
The commands and explanations below attempt to use jq
in the least expensive way, just as means to validate JSON. In my opinion, there are tools better suited for this (Like JSONLint), but if the only thing you have at hand is jq
then this is my contribution.
To validate a JSON file and still get the errors in STDERR
output using jq
you can use the following bash one-liner
jq -reM '""' <<<'<MAYBE_INVALID_JSON>' 1>/dev/null
Which reads as:
Execute jq
with flags:
-r
to output a raw value (No processing or formatting)-e
to exit with a code greater than 0
if there was an error-M
do not colorize JSONThe first jq
argument is '""'
which outputs an empty string, effectively preventing jq
from making any processing of the JSON for printing
<<<
followed by a string is called a "Here String", and is basically telling bash to treat the string as if it was a file and pass it to STDIN
(As input to the command).
Note that you can replace <<<'<MAYBE_INVALID_JSON>'
with the path of a file you want to validate and it would still work
Then redirect any STDOUT
output (Which normally will contain the JSON) to /dev/null
, effectively discarding it
You can also get fancier and output a custom message below the errors by using the following:
jq -reM '""' <<<'<MAYBE_INVALID_JSON>' 1>/dev/null || ( exit_code="$?"; echo 'ERROR: Invalid JSON file. See errors above' 1>&2; exit "$exit_code" )
Where the added portion reads as follows:
||
means: If the previous command failed with a non-zero exit code then run the following command(
. This is actually needed since we want to exit with the original command's exit code
exit_code
environment variable to the exit code of the last command $?
echo
exit
the sub-shell with the exit code from the original command $exit_code
Upvotes: 10
Reputation: 1374
This is working for me
echo $json_string | jq -e . >/dev/null 2>&1 | echo ${PIPESTATUS[1]}
that returns return code:
Then you can evaluate the return code by further code.
Upvotes: 18
Reputation: 74705
From the manual:
-e / --exit-status:
Sets the exit status of jq to 0 if the last output values was neither false nor null, 1 if the last output value was either false or null, or 4 if no valid result was ever produced. Normally jq exits with 2 if there was any usage problem or system error, 3 if there was a jq program compile error, or 0 if the jq program ran.
So you can use:
if jq -e . >/dev/null 2>&1 <<<"$json_string"; then
echo "Parsed JSON successfully and got something other than false/null"
else
echo "Failed to parse JSON, or got false/null"
fi
In fact, if you don't care about distinguishing between the different types of error, then you can just lose the -e
switch. In this case, anything considered to be valid JSON (including false/null) will be parsed successfully by the filter .
and the program will terminate successfully, so the if
branch will be followed.
Upvotes: 78