mvdan / sh

A shell parser, formatter, and interpreter with bash support; includes shfmt
https://pkg.go.dev/mvdan.cc/sh/v3
BSD 3-Clause "New" or "Revised" License
7.21k stars 339 forks source link

Variable transformation does not work with arrays #1081

Open PigeonF opened 3 months ago

PigeonF commented 3 months ago

Using "${array[@]@Q}" does not work as expected (I tried some other operators as well and assume this applies to all operators, not just @Q specifically).

$ bash -c 'var="with space"; echo "${var@Q}"'
'with space'
$ : works as expected
$ gosh -c 'var="with space"; echo "${var@Q}"'
'with space'
$ bash -c 'var=("some" "with space"); echo "${var[@]@Q}"'
'some' 'with space'
$ : does not work as expected
$ gosh -c 'var=("some" "with space"); echo "${var[@]@Q}"'
some with space

As you can see, in the last line the result is not quoted.

theclapp commented 3 months ago

For the unaware (such as myself): The ${parameter@operator} is not in my local bash man page, I had to go looking for it. It came out in bash 4.4, circa late 2015. See https://www.gnu.org/software/bash/manual/html_node/Shell-Parameter-Expansion.html and search for ${parameter@operator}.

The @Q operator:

The expansion is a string that is the value of parameter quoted in a format that can be reused as input.

There are 9 other operators defined in the GNU Bash documentation. This package handles only @Q and @E, everything else panics. See https://github.com/mvdan/sh/blob/793d36450a0a5a466199b04c458fb4a1202cf641/expand/param.go#L315-L337.

Edit: And, obviously, it doesn't work for arrays, regardless.

PigeonF commented 3 months ago

Ah, it seems you are right about only Q and E being supported. I remember trying @K as well, but it seems it did not error because I tried it for arrays. The following "succeeds" in the sense that it does not error, but the output is still wrong (which makes sense if expansion operators are just ignored for arrays)

$ gosh -c 'var=("some" "with space"); echo "${var[@]@K}"'
some with space