如果引用变量为空,如何将其扩展为空?

mur*_*uru 39 bash zsh shell-script variable

说我有一个脚本在做:

some-command "$var1" "$var2" ...
Run Code Online (Sandbox Code Playgroud)

而且,如果var1为空,我宁愿将其替换为空字符串而不是空字符串,以便执行的命令是:

some-command "$var2" ...
Run Code Online (Sandbox Code Playgroud)

并不是:

some-command '' "$var2" ...
Run Code Online (Sandbox Code Playgroud)

有没有比测试变量并有条件地包含它更简单的方法?

if [ -n "$1" ]; then
    some-command "$var1" "$var2" ...
    # or some variant using arrays to build the command
    # args+=("$var1")
else
    some-command "$var2" ...
fi
Run Code Online (Sandbox Code Playgroud)

是否有参数替换可以在 bash、zsh 等中扩展为空?我可能仍然想在其余参数中使用通配符,因此禁用它并取消引用变量不是一种选择。

Mic*_*mer 48

Posix 兼容 shell和Bash 具有 ${parameter:+word}:

如果参数未设置或为空,则应替换为空;否则,扩大字(或如果一个空字符串字被省略)应被取代。

所以你可以这样做:

${var1:+"$var1"}
Run Code Online (Sandbox Code Playgroud)

并且已经var1被检查,"$var1"如果它被设置并且非空(使用普通的双引号规则)就可以使用。否则它扩展为空。请注意,这里只引用了内部部分,而不是整个内容。

这同样适用于 zsh。你必须重复这个变量,所以它并不理想,但它完全符合你的要求。

如果您希望 set-but-empty 变量扩展为空参数,请${var1+"$var1"}改用。

  • 我冒昧地编辑了 `:+` 和 `+` 之间的区别。 (2认同)

Sté*_*las 6

这就是zsh省略引号时默认情况下的操作:

some-command $var1 $var2
Run Code Online (Sandbox Code Playgroud)

其实,为什么你还需要在报价参数周围的zsh扩张的唯一原因是为了避免行为(空去除)作为zsh没有影响其他炮弹其他问题,当你不报价参数扩展(隐裂+球)。

如果您禁用 split 和 glob,您可以对其他类似 POSIX 的 shell 执行相同的操作:

(IFS=; set -o noglob; some-command $var1 $var2)
Run Code Online (Sandbox Code Playgroud)

现在,我认为如果你的变量可以有 0 或 1 值,它应该是一个数组而不是一个标量变量并使用:

some-command "${var1[@]}" "${var2[@]}"
Run Code Online (Sandbox Code Playgroud)

使用var1=(value)whenvar1包含一个值,var1=('')何时包含一个空值,var1=()何时不包含任何值。