Posting an answer here to add a bit of clarification to answers from @acan and @sailnfool. I found that I needed to run through some example scenarios to full grasp the nuances of the method they both describe (thanks to @sailnfool for the example script you created in your answer). At any rate, my comments here would not have been very legible if I simply replied to @sailnfool's post with a comment, so here goes FBO.
Clarifying the logic/outcomes of @sailnfool's script/answer:
- If an array is defined, but a specific element (key) within the array has never been defined: both queries return a result of, "array element does not exist"
- If an array element's value previously existed and has been unset: both queries return "array element does not exist"
- If an array element's (key's) value is not NULL: both queries return "array element exists"
- If an array element's value is NULL: 1st query returns "array element does exist"
- If an array element's value is NULL: 2nd query returns "array element does not exist"
I couldn't quite tell from the original question whether the poster was attempting to derive whether or not a particular array element existed (i.e. whether the specific array element had been declared or not) versus whether or not a particular array element had a value (not null).
If the intent is to determine whether or not a specific array element has ever been set (including setting it equal to NULL), then use this method:
[[ ${arr[c]+1} ]] && echo "array key exists" || echo "array key does not exist"
For example:
declare -A arr
arr["c"]=""
[[ ${arr[c]+1} ]] && echo "array key exists" || echo "array key does not exist"
or
declare -A arr
arr["c"]=''
[[ ${arr[c]+1} ]] && echo "array key exists" || echo "array key does not exist"
If a user's intent is to detect when an array element existed and was subsequently unset, or when a specific array element has never been created, either of the two branching methods are going to return the same result. Namely, that the element does not exist. So, re-capping... the only difference between them is the ability of the first method (examples shown above) to branch when an array element exists but is set equal to NULL. While the 2nd branching method will only return a true path (array element exists) when the array element has been defined, and contains a non-null value.
Bottom Line
Your need scenario 1: tell when an array element is defined and = any value, including NULL
Use: 1st branch method
[[ ${arr[c]+1} ]] && echo "array key exists" || echo "array key does not exist"
Your need scenario 2: tell me when an array element is defined and contains a non-NULL value
Use: either logic branching method
[[ ${arr[c]+1} ]] && echo "array key exists" || echo "array key does not exist"
or
[[ ${arr[c]:+1} ]] && echo "array key exists" || echo "array key does not exist"
Your need scenario 3: tell me when an array element is not defined at all (i.e. never defined or was defined and subsequently unset)
Use: either logic branching method
[[ ${arr[c]+1} ]] && echo "array key exists" || echo "array key does not exist"
or
[[ ${arr[c]:+1} ]] && echo "array key exists" || echo "array key does not exist"