如何让脚本使用“$@”或默认参数列表而不用空格破坏路径?

mil*_*ose 6 shell-script arguments

我想要一个脚本,如果没有参数传递给它,它将在一些默认路径上运行另一个实用程序;理想情况下,我希望这对于包含空格的路径是安全的。

到目前为止我有script.sh

#!/bin/sh
base=$(dirname "$0")
exec touch "${@:-"$base/aaa" "$base/bbb"}"
Run Code Online (Sandbox Code Playgroud)

如果我把它放到一个名为“foo bar”的文件夹中并运行它:

foo\ bar/script.sh
Run Code Online (Sandbox Code Playgroud)

我希望它最终应该这样做:

touch foo\ bar/aaa foo\ bar/bbb
Run Code Online (Sandbox Code Playgroud)

即在脚本所在目录“foo bar”下创建文件“aaa”和“bbb”。

相反,我得到了错误

触摸:无法触摸“foo bar/aaa foo bar/bbb”:没有那个文件或目录

(如果我将参数传递给脚本,它似乎工作正常。大概删除最后一个命令中的外部引号会反转我的情况。)

gle*_*man 10

看来您不能在 的扩展中设置默认参数${@:-...},并且"${@:-"$base/aaa" "$base/bbb"}"被扩展为单个字符串。

如果您想设置默认参数,您可能需要这样做:

base=$(dirname -- "$0")
# test explicitly for no parameters, and set them.
if [ "$#" -eq 0 ]; then
    set -- "$base/aaa" "$base/bbb"
fi
Run Code Online (Sandbox Code Playgroud)

然后,"$@"神奇引用的参数替换可以有增无减:

touch -- "$@"
Run Code Online (Sandbox Code Playgroud)

  • (如果可能的话,我喜欢坚持与 dash 兼容,以免不必要地将 bash 拉入 Docker 镜像。) (2认同)
  • 抱歉,可以在默认扩展中使用多个参数,但仅限于具有数组的 shell。见[我的回答](https://unix.stackexchange.com/a/493990/265604) (2认同)

ImH*_*ere 6

可以在默认扩展中使用多个参数${@-...}

像这样:

#!/bin/bash
base=$(dirname "$0")
arr=("$base/aaa" "$base/bbb")

touch "${@:-"${arr[@]}"}"
Run Code Online (Sandbox Code Playgroud)

但仅限于具有数组(ksh、zsh、bash 等)的 shell。