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.