On Thu, Feb 5, 2015 at 11:02 PM, Chet Ramey <chet.ra...@case.edu> wrote: > On 2/5/15 8:06 AM, isabella parakiss wrote: >> On 2/4/15, konsolebox <konsole...@gmail.com> wrote: >>> Logically that should only unset the elements of an array and not the >>> array variable >>> itself since '*' or '@' is more of a wildcard that represents the >>> indices. However, bash >>> does otherwise: >>> >>> #define ALL_ELEMENT_SUB(c) ((c) == '@' || (c) == '*') >>> >>> ... >>> >>> if (ALL_ELEMENT_SUB (sub[0]) && sub[1] == 0) // If substring is >>> just '@' or '*' >>> { >>> unbind_variable (var->name); // It just removes it. >>> return (0); >>> } >>> >>> Bash version is 4.3.33. >>> >> >> So, this is completely intended. >> May I ask what's the rationale behind this design choice? > > It's a decision that's over twenty years old. It was probably one way > or the other: I didn't want to make it an error, like ksh93, so do you > want array[@] to refer to the array itself or `expand' to all the members. > I chose the former.
I think this is at least something that should be corrected with unset. The consistent way is to just unset all the elements, not the variable itself (if it's an array variable), or print an error message if it's not. On Bash's current implementation, unsetting a non-array actually sends an error message, so why not do it with wildcards as well: # A=1234 # unset 'A[0]' bash: unset: A: not an array variable (Bash version is 4.3.33) > or `expand' to all the members. > I chose the former. Maybe it would just be easy to implement by calling or replicating the functions that are used with A=()? ...Where the condition block where an arrray does not exist or is not an array would just make it show an error message instead of creating a new one. And I'm not sure if the members are necessarily `expanded` in the process. Cheers, konsolebox