How can I expand a quoted variable to nothing if it's empty?

Posix compliant shells and Bash have ${parameter:+word}:

If parameter is unset or null, null shall be substituted; otherwise, the expansion of word (or an empty string if word is omitted) shall be substituted.

So you can just do:

${var1:+"$var1"}

and have var1 be checked, and "$var1" be used if it's set and non-empty (with the ordinary double-quoting rules). Otherwise it expands to nothing. Note that only the inner part is quoted here, not the whole thing.

The same also works in zsh. You have to repeat the variable, so it's not ideal, but it works out exactly as you wanted.

If you want a set-but-empty variable to expand to an empty argument, use ${var1+"$var1"} instead.


That's what zsh does by default when you omit the quotes:

some-command $var1 $var2

Actually, the only reason why you still need quotes in zsh around parameter expansion is to avoid that behaviour (the empty removal) as zsh doesn't have the other problems that affect other shells when you don't quote parameter expansions (the implicit split+glob).

You can do the same with other POSIX-like shells if you disable split and glob:

(IFS=; set -o noglob; some-command $var1 $var2)

Now, I'd argue that if your variable can have either 0 or 1 value, it should be an array and not a scalar variable and use:

some-command "${var1[@]}" "${var2[@]}"

And use var1=(value) when var1 is to contain one value, var1=('') when it's to contain one empty value, and var1=() when it's to contain no value.