I have an array which gets filled with different error messages as my script runs.
I need a way to check if it is empty of not at the end of the script and take a specific action if it is.
I have already tried treating it like a normal VAR and using -z to check it, but that does not seem to work. Is there a way to check if an array is empty or not in Bash?
Supposing your array is
$errors
, just check to see if the count of elements is zero.I generally use arithmetic expansion in this case:
You can also consider the array as a simple variable. In that way, just using
or using the other side
The problem with that solution is that if an array is declared like this:
array=('' foo)
. These checks will report the array as empty, while it is clearly not. (thanks @musiphil!)Using
[ -z "$array[@]" ]
is clearly not a solution neither. Not specifying curly brackets tries to interpret$array
as a string ([@]
is in that case a simple literal string) and is therefore always reported as false: "is the literal string[@]
empty?" Clearly not.I checked it with
bash-4.4.0
:and
bash-4.1.5
:In the latter case you need the following construct:
for it to not fail on empty or unset array. That's if you do
set -eu
like I usually do. This provides for more strict error checking. From the docs:If you don't need that, feel free to omit
:+${array[@]}
part.Also do note, that it's essential to use
[[
operator here, with[
you get:If you want to detect an array with empty elements, like
arr=("" "")
as empty, same asarr=()
You can paste all the elements together and check if the result is zero-length. (Building a flattened copy of the array contents is not ideal for performance if the array could be very large. But hopefully you aren't using bash for programs like that...)
But
"${arr[*]}"
expands with elements separated by the first character ofIFS
. So you need to save/restore IFS and doIFS=''
to make this work, or else check that the string length == # of array elements - 1. (An array ofn
elements hasn-1
separators). To deal with that off-by-one, it's easiest to pad the concatenation by 1test case with
set -x
Unfortunately this fails for
arr=()
:[[ 1 -ne 0 ]]
. So you'd need to check for actually empty arrays first separately.Or with
IFS=''
. Probably you'd want to save/restore IFS instead of using a subshell, because you can't get a result out of a subshell easily.example:
does work with
arr=()
- it's still just the empty string.I prefer to use double brackets:
In my case, the second Answer was not enough because there could be whitespaces. I came along with:
You could also benefit from jq if you got it installed on your system:
Sadly I cannot comment yet - Regarding @Nick Tsai - I didn't work for me but the following:
spacing is important for this to work!