jq shouldn't return 0 on an empty file with a nonexistent key

Created on 10 Jan 2020  路  6Comments  路  Source: stedolan/jq

Describe the bug

When using jq to open an empty file, and a query of printing a particular key (which can't exist, because the file is empty), the return status is success (0). But it clearly didn't succeed in querying the key, because it didn't exist.

To Reproduce

vagrant@vagrant:~$ jq -r .foo /dev/null
vagrant@vagrant:~$ echo $?
0
vagrant@vagrant:~$ jq --version
jq-1.6

Expected behavior

Returns non-zero status.

Environment (please complete the following information):

  • OS and Version: Linux Ubuntu 18.04.3
  • jq version: 1.6
not a bug

All 6 comments

You may be interested in the -e/--exit-status option.

Otherwise, this is the expected behaviour; jq successfully applied the filter to all zero inputs.

hi, @pwillis-els
you may be interested in this doc.
https://github.com/stedolan/jq/blob/master/docs/content/manual/manual.yml line:218

   * `-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.
        Another way to set the exit status is with the `halt_error`
        builtin function.


test result

root@qq-001:test# ./jq/jq -r -e '.foo' /dev/null
root@qq-001:test# echo $?
4

Huh, did not know about that option! Thanks, if this is expected behavior i'll close issue

Re-opening this, I think there is still a case for some kind of error for this particular use case.

$ echo '[[{"name":"something","id":12345}]]' | jq -e -r '.[][] | [ .name, .id|tostring ] | join(",")'
something,12345
$ echo $?
0
$ echo '{"foo": "bar"}' | jq -e -r '.[][] | [ .name, .id|tostring ] | join(",")'
jq: error (at <stdin>:1): Cannot iterate over string ("bar")
$ echo $?
5
$ echo '[{}]' | jq -e -r '.[][] | [ .name, .id|tostring ] | join(",")'
$ echo $?
4
$ echo '' | jq -e -r '.[][] | [ .name, .id|tostring ] | join(",")'
$ echo $?
0

With -e option, failure to query the stream will return an error in different conditions. But if the stream is empty, it returns success.

This is a similar problem as noted in the following issue: https://github.com/stedolan/jq/issues/1142

Having to implement complicated workarounds every time you run jq, in the off-chance that the input was either a pipe or a file that was empty, just seems like poor design that could be fixed with a feature flag (that I would enable every single time I ran jq, and I wager most other people would as well).

It could be that this is a problem with my version of jq?

$ jq --version
jq-1.6
$ jq -r -e '.foo' /dev/null
$ echo $?
0

I would expect that at least the has() function would be able to catch this?

echo '' | jq -e 'has("foobar")'; echo $?
0

because clearly that is wrong?

It will fail on malformed json:

echo '123' | jq -e 'has("foobar")'; echo $?
jq: error (at <stdin>:1): Cannot check whether number has a string key
5

and also if the element is really not there:

echo '{}' | jq -e 'has("foobar")'; echo $?
false
1
Was this page helpful?
0 / 5 - 0 ratings