mainThe GNU Bourne-Again SHell - Support: sr #109139, Unset on certain elements of...

 
 

sr #109139: Unset on certain elements of associative arrays does not work as expected

Submitter:  Maxxim <maxxim>
Submitted:  Sat 10 Sep 2016 05:34:35 PM UTC
   
 
Category:  None Priority:  5 - Normal
Severity:  3 - Normal Status:  Done
Privacy:  Public Assigned to:  None
Open/Closed:  Open Operating System:  GNU/Linux
* Mandatory Fields

Add a New Comment Rich Markup
   

Tue 17 Jan 2023 10:25:36 PM UTC, comment #5: 

These examples all work as expected in bash-5.2.

Chet Ramey <chet>
Group administrator
Sun 16 Oct 2016 09:13:11 PM UTC, comment #4: 

1. Probably not.  There were several bug fixes regarding associative array subscript parsing between bash-4.3 and bash-4.4.

2. I have considered it, but there is many years' worth of backwards compatibility to consider as well.

Chet Ramey <chet>
Group administrator
Sat 01 Oct 2016 02:46:07 PM UTC, comment #3: 

Thank you for your reply. Two questions remain:

1) Is there a way to make the example work in Bash 4.3? I couldn't quite figure that out from the conversation you referred to. (Bash 4.4 is not yet stable in my distribution as of writing this)

2) Even if that works, it's not intuitive at all. Isn't it possible to change the way unset works to a more intuitive, let's say 'developer-friendly' way?

Maxxim <maxxim>
Sun 25 Sep 2016 04:26:58 PM UTC, comment #2: 

When bash resolves an array reference, it dynamically expands
the subscript as part of obtaining its value.  There is a good
posting on help-bash explaining why bash does this:

http://lists.gnu.org/archive/html/help-bash/2016-09/msg00021.html

My reply points out that you need to quote the brackets to be
safe, since the word is subject to filename expansion.  The
unset builtin assumes that the word has been quoted and that the
subscript needs to be expanded as part of figuring out which
element to unset.

You can make your example work in bash-4.4 by single-quoting the
arguments to unset and assuming that the subscript will be run
through the usual set of word expansions:

unset 'testdict[\"hey you\"]'


Chet Ramey <chet>
Group administrator
Mon 12 Sep 2016 01:10:04 PM UTC, comment #1: 

There seem to be countless other examples, e.g.

# declare -A testdict=( ["\"hey you\""]="test" )
# unset testdict["\"hey you\""]
bash: unset: testdict["hey you"]: bad array subscript
# unset testdict['"hey you"']
bash: unset: testdict["hey you"]: bad array subscript

which suggests that the way unset interprets associative arrays is completely flawed.

Maxxim <maxxim>
Sat 10 Sep 2016 05:34:35 PM UTC, original submission:  

While working on a project that uses associative arrays to store data, I discovered the following unexpected behaviour:

# declare -A testdict=( ["[]"]="" )
# unset testdict["[]"]
# echo ${!testdict[@]}
[]

The unset command seems to have no effect. After trying all variations of the unset command (quoting, escaping etc.) I could think of, I finally found one that works:

# unset testdict["\[]"]

Although that solves that specific problem, I found another item which can't be unset no matter what unset variation I tried:

# declare -A testdict=( ["]"]="" )

I think it's worth mentioning that the problem only seems to occur with square brackets - parentheses, braces etc. don't cause any trouble.

I'm using Bash 4.3_p42 on Gentoo Linux (x64).

Maxxim <maxxim>

 

(Note: upload size limit is set to 16384 kB, after insertion of the required escape characters.)

Attach Files:
   
   
Comment:
   

No files currently attached

 

Depends on the following items: None found

Items that depend on this one: None found

 

Carbon-Copy List
  • -email is unavailable- added by chet (Posted a comment)
  • -email is unavailable- added by maxxim (Submitted the item)
  •  

    There are 0 votes so far. Votes easily highlight which items people would like to see resolved in priority, independently of the priority of the item set by tracker managers.

    Only logged-in users can vote.

     

    Follow 2 latest changes.

    Date Changed by Updated Field Previous Value => Replaced by
    2023-01-17 chet StatusPostponed Done
    2016-09-25 chet StatusNone Postponed

    Back to the top

    Powered by Savane 3.13-758e.
    Corresponding source code