On Mon, Jun 16, 2025 at 18:51:23 +0200, Lionel Cons wrote:
> Why do these two lines differ in output? ${name} and ${name-} should
> produce identical output if "name" exists as variable, or not?
>
> $ (name='bar" x' ; name="${name-//\"/}" ; printf "%q\n" "$name")
> 'bar" x'
> $ (name='bar" x' ; name="${name//\"/}" ; printf "%q\n" "$name")
> 'bar x'
In the first one, you appear to be trying to combine ${var-default} and
${var/replacement} together. This isn't valid.
What's actually happening is you're using the ${var-default} syntax
exclusively, and the "default" in this case happens to be //"/ .
An English translation would be "expand to the value of var, unless
var is unset, in which case expand to the literal string //"/".
hobbit:~$ name='bar" x'
hobbit:~$ unset -v noname
hobbit:~$ echo "${name-//\"/}"
bar" x
hobbit:~$ echo "${noname-//\"/}"
//"/
If the goal of adding the "-" was to work around set -u, then the obvious
solution would be to stop using set -u. Otherwise, you're going to have
to do this in two separate steps. You can't chain different parameter
expansions together in this way.
tmp=${name-}
echo "${tmp//\"/}"
# or similar
My own preference would be to stop using set -u. It breaks more than it
fixes.