1

In Bash test if associative array is declared

I want to test a variable is declared as an associative array or not. I see the above discussion. But it is not clear which one is the best.

The following mentioned on the above link, but does not work.

declare -A x; [[ -v x[@] ]]; echo "$?"

This is costly. It has to print the whole data structure. It can be slow when the data is large.

[[ "$(declare -p FOO 2>/dev/null)" == "declare -A"* ]]

What is the best way to check whether a variable is an associative array?

EDIT: The answer below is the best for Bash 5. The results on the link at the top of the message are obsolete and those methods should be ignored for Bash 5.

  • Please add your (useful!) answer to the preexisting question. – Charles Duffy Apr 01 '21 at 00:15
  • No. That is a very bad idea. –  Apr 01 '21 at 00:20
  • 1
    How so? The point of merging questions is to get more attention -- right now, people who see the existing question won't be able to find your answer. – Charles Duffy Apr 01 '21 at 00:26
  • _Because_ the existing question has more eyes (more views, more presence in search engine indices -- and is already the target of _other_ duplicate flags), if you don't move your answer, I'll build my own version of it there -- but it would be better for you to get the credit yourself, since you did the research. – Charles Duffy Apr 01 '21 at 00:33

1 Answers1

4

The following can be used to test whether a bash variable is an associative array.

[[ ${x@a} = A ]]

${x@a} can be used to test whether it is a variable and an array as well.

$ declare x; echo "${x@a}"

$ declare -a y; echo "${y@a}"
a
$ declare -A z; echo "${z@a}"
A
  • Am I correct to believe that this is a bash 5.0 feature, and not portable back to 3.x or 4.x series? – Charles Duffy Mar 31 '21 at 23:28
  • I am not sure how early it goes back to. I only have bash 5 to test. –  Mar 31 '21 at 23:52
  • To be clear, I'm pretty sure you could add this as a new answer to the existing question (to be extending it to cover newer bash versions than the existing answers were written for). – Charles Duffy Mar 31 '21 at 23:54
  • ...the `@` suffix expansions were mostly added in 5.0, as a group. – Charles Duffy Mar 31 '21 at 23:54
  • I don't think it is a good idea to merge with the old thread. No answers of there are of practical use. It is too bad to show both bad answers and good answers. The old bad answers should be just ignored. This questions should not be closed. –  Apr 01 '21 at 00:18
  • The "bad" answers are still useful to people who need compatibility with ancient versions of bash, like the one that ships with MacOS (and for that matter, several long-term-support versions of Linux that are still supported with bash 4.x). More to the point, someone who's looking at the old question right now will think the bad answers are the only ones that exist; they won't be able to learn from the more up-to-date information you're adding. – Charles Duffy Apr 01 '21 at 00:27
  • If you want folks to see your answer above the older ones, the way to do that is to ask the person who asked the other question to move the checkmark to your answer -- but you can only do that after you move the answer to that other question. – Charles Duffy Apr 01 '21 at 00:29
  • No. This is a bad idea. That person may not respond. –  Apr 01 '21 at 00:33
  • You keep repeating that it's a bad idea, but adding new answers to old questions (as/when better answers become available) is how Stack Overflow works. If you want to challenge that, ask a question about it on [meta], which is where we debate and arrive on consensus around our rules. – Charles Duffy Apr 01 '21 at 00:35
  • (Also, I happen to recognize the person who asked the other question, and they're a well-known, active user). – Charles Duffy Apr 01 '21 at 00:35
  • (Many of the other users with answers on that question are _also_ well-known, active users; if you asked politely, I wouldn't be surprised if they were willing to edit their answers to qualify that they're only appropriate for use when compatibility with older releases of the shell is required). – Charles Duffy Apr 01 '21 at 00:39
  • It is just a waste of time. If this thread is a good one, google will rank it the top. There is not point to waste so much time on merging it. That is why it is a bad idea to hang on this issue. –  Apr 01 '21 at 01:00
  • Googlebot doesn't evaluate technical merit. It evaluates number of links, and an older question will have more (_especially_ since every time a question is re-asked, the new copy gets closed with a link to the old one, giving the old one more "Google juice"). Once again: The place to argue your case if you think our rules should be changed is [meta]. Any of us old-timers will respect it if consensus on meta agrees that we're wrong. – Charles Duffy Apr 01 '21 at 01:57
  • Reposted community-wiki @ https://stackoverflow.com/a/66897754/14122 – Charles Duffy Apr 01 '21 at 02:39
  • No time to argue about this. But stackoverflow is going a completely wrong direction in closing too many posts. –  Apr 01 '21 at 02:54
  • If I may add an external eye on this thread, I think that Charles Duffy is right here. I would never have known your better answer if Charles hadn't copied it to the original question. Answers may become "bad" over time because SW change over time. Nothing prevents new answer to be upvoted above accepted answers. I prefer to scan for all answers to one question than to scan for possible question duplicates. – fuujuhi Apr 03 '21 at 15:54
  • @fuujuhi I don't. I am sick of long thread full of bad answers. –  Apr 03 '21 at 15:59