Re: ="${!a[@]}" expands incorrectly bash 5.1 and above + patch

Emanuele Torre <[email protected]> Mon, 25 May 2026 11:12:38 +0200
Newsgroups gmane.comp.shells.bash.bugs
Message-ID <ahQShj7dTwQVDTfT@ntoo>
On Sun, May 24, 2026 at 12:47:12PM +0200, Emanuele Torre wrote:
> On Sun, May 24, 2026 at 11:31:51AM +0200, Emanuele Torre wrote:
> > The current order of these cases does not seem logical to me; it is
> > probably incorrect: I would expect the PF_ASSIGNRHS case not to care
> > about whether the expansion is quoted, and thus also to take precedence
> > over the case for double quoted expansions outside of assignments.
> > 
> > Unless I am missing something, reordering those two cases seems to fix
> > the regression; so, the fix probably looks similar to something like
> > this:
> 
> I will point out that this patch also changes the behaviour of  [@]@k
> in assignments, and maybe also that of some other @OP expansions, to
> one which I would think is more correct:
> 
> bash-5.3.9
>   $ IFS=+ a=(a b) b=${a[*]@k}; declare -p b
>   declare -- b="0+a+1+b"
>   $ IFS=+ a=(a b) b=${a[@]@k}; declare -p b
>   declare -- b="0+a+1+b"
>   $ IFS=  a=(a b) b=${a[*]@k}; declare -p b
>   declare -- b="0a1b"
>   $ IFS=  a=(a b) b=${a[@]@k}; declare -p b
>   declare -- b="0 a 1 b"
> 
> devel (2d4ba0c618584d3554165b9484d921ec8c4e4523) with the patch applied
>   $ IFS=+ a=(a b) b=${a[*]@k}; declare -p b
>   declare -- b="0+a+1+b"
>   $ IFS=+ a=(a b) b=${a[@]@k}; declare -p b
>   declare -- b="0 a 1 b"
>   $ IFS=  a=(a b) b=${a[*]@k}; declare -p b
>   declare -- b="0a1b"
>   $ IFS=  a=(a b) b=${a[@]@k}; declare -p b
>   declare -- b="0 a 1 b"
> 
> That is, [@] → " " and [*] → IFS  as opposed to the current  IFS  for
> both unless IFS='', in which case [@] → " ", [*] → "".
> 
> o/
>  emanuele6

Apparently I already made a similar report regarding  =${@/} and =${@:}
vs ="${@/}" and ="${@:}" last year, which I completely forgot about!

https://lists.gnu.org/archive/html/bug-bash/2025-11/msg00048.html

The patch I posted in this thread also takes care of them, and even
=${@@Q} ="${@@Q}" =${@#?} ="${@#?}" =${@%?} ="${@%?}" etc. always using
IFS (unless IFS is empty, unless the pattern is empty) rather than space
which was also mentioned in the other report.

bash-5.3.9
  $ set a b c; IFS=: o=${@@Q} u="${@@Q}"; declare -p o u
  declare -- o="'a':'b':'c'"
  declare -- u="'a':'b':'c'

devel (2d4ba0c618584d3554165b9484d921ec8c4e4523)
  $ set a b c; IFS=: o=${@@Q} u="${@@Q}"; declare -p o u
  declare -- o="'a' 'b' 'c'"
  declare -- u="'a':'b':'c'

devel (2d4ba0c618584d3554165b9484d921ec8c4e4523) with the patch applied
  $ set a b c; IFS=: o=${@@Q} u="${@@Q}"; declare -p o u
  declare -- o="'a' 'b' 'c'"
  declare -- u="'a' 'b' 'c'

o/
 emanuele6