[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Behaviour of test -v with assoc array and quote character in key
From: |
Daniel Gröber |
Subject: |
Re: Behaviour of test -v with assoc array and quote character in key |
Date: |
Mon, 15 Feb 2021 19:28:22 +0100 |
User-agent: |
NeoMutt/20180716 |
Hi Greg and Chet,
On Mon, Feb 15, 2021 at 08:48:15AM -0500, Greg Wooledge wrote:
> Do it this way instead:
>
> unicorn:~$ mytest() { array[$1]=123; test -v 'array[$1]'; echo "$?"; }
Ah! I didn't know test would exand that '$1' in there, cool.
> Yours expands $1 first, then passes array["] as an argument to test,
> which then performs a *second* round of expansion/parsing.
Right that's sort of what I figured I was seeing and I wasn't sure if this
is intentional.
> You might also want to look at the assoc_expand_once option, although
> single-quoting will work in a wider range of bash versions.
Thanks for the tip!
On Mon, Feb 15, 2021 at 09:11:48AM -0500, Chet Ramey wrote:
> `test' is always going to be problematic here because, as a shell builtin,
> its arguments undergo a round of word expansions before it's invoked. It's
> difficult to reliably detect the closing bracket in an array subscript as a
> result, even if the array subscript expansion didn't perform any expansions
> on its own. (Consider what would happen if $1 were `]').
You're absolutely right, I didn't consider the ']' case at all! That would
obviously break. So indeed this just user-error then and not really a bug.
> There are workarounds you can use to avoid the problem, involving adding a
> set of quotes to suppress the expansion the array subscript evaluation
> performs.
The `test -v 'array[$var]'` thing Greg suggested above seems pretty good to
me. Since the array subscript expands variables internally (which I didn't
know) that seems to be the way to go.
The workaround I came up with left to my own devices was to use eval
`printf %q`, I assume that's the sort of quoting you were referring to:
# Usage: array_key_exists ARRAY KEY
#
# The ARRAY argument must be a valid bash identifier, but this is not
# checked. KEY may be any string.
#
array_key_exists () {
eval "[ -n \"\${$1[$(printf '%q' "$2")]:-}\" ]"
}
I was also wondering how array subscript interacts with `[[`, but it seems that
[[ -v array[']'] ]]
has the same problem as `test`. Looking at the manual it says that while
word splitting and filename expansion isn't performed quote removal still
is so that's no help in this regard.
I wonder if this particular point, how to check an arbitrary array key
exists or not, is documented anywhere yet? I'd be happy to send a
patch. Can someone point me to the sections in the man{ual,page} that could
use commentary for this?
Thanks,
Daniel
- Behaviour of test -v with assoc array and quote character in key, Daniel Gröber, 2021/02/14
- Re: Behaviour of test -v with assoc array and quote character in key, Greg Wooledge, 2021/02/15
- Re: Behaviour of test -v with assoc array and quote character in key, Chet Ramey, 2021/02/15
- Re: Behaviour of test -v with assoc array and quote character in key, Andreas Schwab, 2021/02/23
- Re: Behaviour of test -v with assoc array and quote character in key, Greg Wooledge, 2021/02/23
- Re: Behaviour of test -v with assoc array and quote character in key, Oğuz, 2021/02/23