10

Two things, first this is my first question in this forum and I do apologise if the formating is all over the place. Second I have not written that many bash scripts, and it tend to be quite a long time between the scripts I produce.

That said, here is my question.

Is it possible to do something like this in bash (Clear array $array contains):
$array=()

Basically this is what I would like to do. I have a variable with array variable names in it:

array1=()  
array2=()  
arrayList="array1 array2"  


# In a function far far away
for array in $arrayList
do  
    eval arr=("\"\${$array[@]\"")  

    for index in ${!arr[@]}
    do
        echo "${arr[$index]}"
    done
    # Here is the big "?", I like to clear the array that $array refers to.
    $array=()  
done

My arrays contain strings that include "" (space) and this is why I use the eval statement. Not sure it's needed but at least it's working. The script is more or less working as I want it too, but I need to clear the arrays in the $arrayList, and I rather not hardcode it somewhere, even though that would be easy.

4
  • See mywiki.wooledge.org/BashFAQ/048 re: use of eval -- short form is that it's really not an advised practice. Commented May 8, 2012 at 11:26
  • Thanks for the link! I read that eval is not a recommended way to go since you can inject bad stuff in it, or even do some stupid stuff yourself if not careful what you evel. I will consider swaping it for another solution, even though this script will only be used by myself. Commented May 8, 2012 at 11:36
  • Maybe what you really want is associative arrays. They're available in bash 4. Commented May 8, 2012 at 11:45
  • @Dunes Hmm, you are probably right. Was just reading about them on the link to BashFAQ #6 that Charles Duffy provided in his answer below. Thanks. Commented May 8, 2012 at 11:54

3 Answers 3

12

Probably the simplest thing to do is just unset them. An unset variable will act identically to an empty array in most contexts, and unset $array ought to work fine.

Sign up to request clarification or add additional context in comments.

4 Comments

You mean it could it be that easy? :) I kind of thought it would just unset the $array variable leaving $array1 and $array2 intact. But after testing your suggestion it do looks promising. Thanks a bunch!
@Qben unset array would unset the array variable itself; unset $array works as-advertised.
@Qben: When you unset indirectly like that I recommend quoting the variable: unset "$array"
Using unset will cause you to lose any properties of the variable. For example, I had a local variable, I unset it, and now it is no longer local and breaks everything. As much as it pains me, eval "$1=()" is the only thing that works for me :-\
1

You can't do $foo=bar ever -- that isn't how indirect assignments in bash work. Unfortunately, while being able to do indirect array assignments is an available feature in ksh93, it isn't a formally documented available feature in bash.

Quoting BashFAQ #6 (which should be read in full if you're interested in knowing more about using indirect variables in general):

We are not aware of any trick that can duplicate that functionality in POSIX or Bourne shells (short of using eval, which is extremely difficult to do securely). Bash can almost do it -- some indirect array tricks work, and others do not, and we do not know whether the syntax involved will remain stable in future releases. So, consider this a use at your own risk hack.

# Bash -- trick #1.  Seems to work in bash 2 and up.
realarray=(...) ref=realarray; index=2
tmp="$ref[$index]"
echo "${!tmp}"            # gives array element [2]

# Bash -- trick #2.  Seems to work in bash 3 and up.
# Does NOT work in bash 2.05b.
tmp="$ref[@]"
printf "<%s> " "${!tmp}"; echo    # Iterate whole array.

However, clearing is simpler, as unset $array will work fine.

4 Comments

I dont think he wants dereferencing, he just wants to empty the array
@c00kiemon5ter sure, but but answering only how to empty an array will leave someone wondering whenever they're trying to do something else. I've added a directly-on-point answer, but think there's value to answering the larger question of "what should I do instead of $array=..."?
Indirect assignments can be done like this: declare $foo=bar
@DennisWilliamson ...or with printf -v "$foo" '%s' bar, or with any of the other mechanisms given in the linked FAQ. It's not hard for non-array variables -- "You can't do $foo=bar ever" was meant only to mean that assignments with a $ on the left side aren't valid even for non-arrays, not that no working syntax existed anywhere.
-1
array=()

It clears the array. I guess that is what you wanted..

1 Comment

No, it's not, you missed the point. The question is about indirection.

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.