shell:可变参数的默认值($@)

shell: default values for varargs ($@)

所以我正在编写一个 shell 脚本,它接受可选参数(用 getopts 解析它们,什么不是;但这在这里并不重要)。

(脚本的)用户应该传递一些路径作为参数,然后由一些主力实用程序处理。 当然路径可能包含空格,所以我用双引号 ("$@") 传递参数,还有许多其他标志:

像这样:

workhorse        \
  --verbose      \
  --stats        \
  --one-flag     \
  --another-flag \
  "$@"

一切正常,但是:

如果用户没有指定任何路径,我想回退到一些默认值。 我不知道如何实现这一目标,同时仍然 能够处理空格 而不是。

天真的方法是这样的:

if [ $# -gt 0 ]; then
  workhorse        \
    --verbose      \
    --stats        \
    --one-flag     \
    --another-flag \
    "$@"
else
  workhorse        \
    --verbose      \
    --stats        \
    --one-flag     \
    --another-flag \
    /home/foo /home/bar
fi

但这当然很难看。 相反,我想使用变量替换,将 $@ 替换为默认值,如下所示:

default_paths="/home/foo /home/bar"
workhorse        \
  --verbose      \
  --stats        \
  --one-flag     \
  --another-flag \
  ${@:-${default_paths}}

这有效,只要通过 cmdline 传递的路径不包含任何空格($@ 周围没有双引号)。 为了支持 args 中的空格,我会使用双引号,但 "${@:-${default_paths}" 将(在正确扩展 cmdline-args 的同时)将 /home/foo /home/bar 字符串作为单个参数传递给我的主力。

我可以通过将标志放入 $flags 变量中来简化上面的“丑陋”解决方案(只是以不同方式调用主力,具体取决于是否有任何 cmdline 提供的路径)如果这些标志本身可以包含(带有)空格怎么办?

那么:有没有办法为可以包含空格的可变 shell 参数提供默认值?

类似 shift 的逆运算可能会有所帮助(将新参数推送到位置参数队列)

我正在寻找符合 POSIX 的解决方案(而不是 bash-数组)。

如果您可以控制 default_paths 在脚本中的设置方式,那么您可以只使用 set 将路径分配为位置参数

if [ $# -eq 0 ]; then
  set -- "/home/foo" "/home/bar" "/home/path with spaces"
fi

并继续使用 "$@" 作为参数列表。