jq -e always returns 0 for empty input

Created on 5 May 2016  Â·  4Comments  Â·  Source: stedolan/jq

jq -e always exits with status 0 when passed empty input. For example:

$ echo | jq --exit-status 'false'; echo $?
0

Consider a use case like this one:

call-some-json-api |
jq --exit-status '.field == "some-value"' &&
take-action

If the API call fails and output is only written to stderr, take-action will still run as though the call succeeded, and "some-value" had been set.

This may be related to issue #667, but that one has been fixed on master, and this bug is still present.

Most helpful comment

another workaround:

$ echo | jq -es 'if . == [] then null else .[] | your-pipe end'
$ echo $?
1

All 4 comments

A minor (one line) change to my fix proposal (PR #1140) for related #1139 issue should fix this.
Simply change the default ret value to '4' would break --exit-status semantics,
(it would always return 4 in such a case, while it should return 0 if -e is not set)

Exactly, @rfletcher! With the current behavior of jq -e, the calling script is forced to either call the input command twice or saving the result in some intermediate buffer to avoid calling it a second time.

I ended up with a workaround like this in my script:

  # Exit with failure code (1) if we have no input
  # Otherwise jq will happily exit with 0 (https://github.com/stedolan/jq/issues/1142)
  some_input_script &>/dev/null || exit 1
  some_input_script | jq --exit-status ".$key == true" >/dev/null

There appears to be no way to handle or work around this with just a single jq filter/invocation — but there should be! (Even if we had to add another flag, like ~--empty-input-as-failure~ (or --empty-input-as-null, see #1628), that would be better than nothing.)

By the way, this issue came up again in #1497.

For anyone who (like me) comes across this trying to check whether a file is valid json, you can use one of these workarounds until the underlying jq issue is fixed:

To just check that filename.json is valid json:
[ -s filename.json ] && jq -e . filename.json && echo filename.json is valid || echo invalid json

To also check for the presence of a .foo key:
[ -s filename.json ] && jq -e .foo filename.json && echo filename.json contains .foo || echo nope

another workaround:

$ echo | jq -es 'if . == [] then null else .[] | your-pipe end'
$ echo $?
1
Was this page helpful?
0 / 5 - 0 ratings

Related issues

mcandre picture mcandre  Â·  3Comments

thedward picture thedward  Â·  3Comments

rokka-n picture rokka-n  Â·  4Comments

benjamin-bin-shen picture benjamin-bin-shen  Â·  3Comments

ve3ied picture ve3ied  Â·  4Comments