I was using this code to use jq to format a json file in place
jq . foo.json | sponge foo.json
It works great, but has one fatal flaw – if jq . foo.json
fails (due to, say, a parsing error), the pipe just keeps on tickin and writes nothing to foo.json
, wiping the file.
The behavior I want is something that is the same as foo | bar
, but if foo
fails, bar
will not be executed. set -o pipefail
seemed promising, but it turns out that’s not what it does. This feels like a common enough use case that there would be some clever shorthand for it, but I can’t figure it out.
0
Can you share the json file?
You could try this.
jq . foo.json > temp.json && mv temp.json foo.json
This will first run jq . foo.json > temp.json.
If jq succeeds, it will move temp.json to foo.json, overwriting it with the formatted JSON.
If jq fails, temp.json won’t be updated, and foo.json will remain unchanged.
Update:
if jq . foo.json > foo.json.tmp && mv foo.json.tmp foo.json; then
echo "JSON formatted successfully"
else
echo "Failed to format JSON"
rm -f foo.json.tmp
fi
Or you could try this, it will write the output to dev/null instead of creating a file.
jq . foo.json > foo.json.tmp 2>/dev/null && mv foo.json.tmp foo.json
If you want to try the try/catch function from jq I think it would go something like this.
jq 'try . catch empty' foo.json > foo.json.tmp && mv foo.json.tmp foo.json
4
jq perfectly handles that, with try/catch feature:
see docs here
2