3

I have a bash script:

#! /bin/bash

someId=$(curl -sk -H -X POST -d "fizzbuzz" "https://someapi.example.com/v1/orders/fire" | jq '.someId')

if [ -z "$someId" ]; then
  echo "Order Placement failed; unable to parse someId from the response"
  exit 1
fi

echo "...order $someId placed"

When I run this I get the following output:

...order null placed

So somehow $someId is null but then...shouldn't I be seeing the "Order Placement failed; unable to parse someId from the response" echo instead?

How can I modify the if [ -z "$someId" ]; then conditional to execute if $someId is null?

2
  • 2
    the string "null" is not zero-length, it's four bytes. -z checks only for zero-length strings. Commented Jul 28, 2020 at 18:02
  • 1
    Sounds like what you want is more like [ -z "$someId" ] || [ "$someId" = null ] (splitting it into two separate tests that way complies with current POSIX guidelines; see the OB markers in pubs.opengroup.org/onlinepubs/9699919799/utilities/test.html, flagging other ways to combine tests as obsolescent). Commented Jul 28, 2020 at 18:03

2 Answers 2

6

Use the --exit-status option, which makes jq have a non-zero exit status if the last output value is false or null.

#! /bin/bash


if ! someId=$(curl -sk -H -X POST -d "fizzbuzz" "https://someapi.example.com/v1/orders/fire" | jq -r --exit-status '.someId'); then
  echo "Order Placement failed; unable to parse someId from the response"
  exit 1
fi

echo "...order $someId placed"
Sign up to request clarification or add additional context in comments.

2 Comments

Should that be if ! someId=...?
Also jq -j or jq -r would be more appropriate to transmit the someId content, or the value returned is of the JSON format that is not appropriate in most cases for shell, like a null in JSON is the null keyword.
3

The "null string" is an empty string -- a zero-byte string, that is, a string with no characters contained within it. s="" assigns a null string to the variable s, just as s= or s='' do.

s=null, or s='null', or s="null", by contrast, assign a string with the four-byte string null (and then terminated by a literal NUL character, as all C strings are). These strings are not "null strings" or "empty strings" in the sense that test -z "$s" or [ -z "$s" ] check for: It doesn't have zero characters; instead, it has four (those being n, u, l and l).

To detect either an empty string or the non-empty string "null", use instead:

if [ -z "$someId" ] || [ "$someId" = null ]; then
  echo "Order Placement failed; unable to parse someId from the response"
  exit 1
fi

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.