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.

Reply via email to