假设我有一个脚本在做:
some-command "$var1" "$var2" ...
而且,如果var1
为空,我宁愿将其替换为空字符串而不是空字符串,以便执行的命令为:
some-command "$var2" ...
并不是:
some-command '' "$var2" ...
有没有比测试变量并有条件地包含它更简单的方法?
if [ -n "$1" ]; then
some-command "$var1" "$var2" ...
# or some variant using arrays to build the command
# args+=("$var1")
else
some-command "$var2" ...
fi
是否有参数替换可以在 bash、zsh 等中扩展为空?我可能仍想在其余参数中使用通配符,因此禁用它并取消引用变量不是一种选择。
符合 Posix 的 shell和Bash 具有
${parameter:+word}
:所以你可以这样做:
并且已经过
var1
检查,"$var1"
如果它已设置且非空(使用普通的双引号规则),则可以使用它。否则它会扩展为空。请注意,这里仅引用内部部分,而不是全部内容。这同样适用于 zsh。你必须重复这个变量,所以它并不理想,但它完全符合你的要求。
如果您希望将设置但为空的变量扩展为空参数,请
${var1+"$var1"}
改用。当您
zsh
省略引号时,默认情况下会这样做:实际上,您仍然需要在 zsh 中围绕参数扩展引用引号的唯一原因是避免这种行为(空删除),因为当您
zsh
不引用参数扩展(隐式 split+全球)。如果禁用 split 和 glob,则可以对其他类似 POSIX 的 shell 执行相同操作:
现在,我认为如果你的变量可以有 0 或 1 值,它应该是一个数组而不是一个标量变量并使用:
并使用
var1=(value)
whenvar1
is 包含一个值,var1=('')
何时包含一个空值,以及var1=()
何时包含不包含值。我在一个 bash 脚本中使用 rsync 遇到了这个问题,该脚本启动了带有或不带有 a
-n
来切换空运行的命令。事实证明,rsync 和许多 gnu 命令将''
作为有效的第一个参数,并且与不存在时的行为不同。由于空参数几乎完全不可见,因此调试需要相当长的时间。
rsync 列表中的某个人向我展示了一种避免此问题的方法,同时也大大简化了我的编码。如果我理解正确,这是@Stéphane Chazelas 最后一个建议的变体。
在许多单独的变量中构建您的命令参数。这些可以按照适合问题的任何顺序或逻辑进行设置。
然后,最后,使用变量构造一个数组,将所有内容都放在适当的位置,并将其用作实际命令的参数。
这样,命令仅在代码中的一个位置发出,而不是针对参数的每个变体重复。
使用此方法,任何为空的变量都会消失。
我知道使用 eval 是非常不受欢迎的。我不记得所有的细节,但我似乎需要它来让事情以这种方式工作——这与处理带有嵌入空白的参数有关。
例子: