Bourne shell:如何将$2到$N个参数发送给可变函数?

13

谷歌终于让我失望了。我似乎无法找到如何在 Bourne shell 脚本中实现以下操作:

我正在编写一个shell脚本来处理我项目中的所有测试。我已经为该脚本可以执行的每个任务设置了函数(构建、运行、清理等),并希望将除命令本身以外的任何其他命令行参数传递给所需的函数。

例如:

./test.sh build -j 应该将 -j 传递给 build 函数。

这种逻辑的伪代码版本如下:

function build() {
   make $*
}

if [ $1 == 'build' ]; then
   build $2 -> $N
fi

我该如何实现这个?

3个回答

20

我认为你可以使用shift命令实现该效果。它将所有位置参数向下移动一个位置并丢弃$1的值(因此将$3的值移动到$2,将$2的值移动到$1,而$1的值则丢失)。完成后,您只需使用$@来获取您实际感兴趣的参数列表即可,例如:

function build() {
    echo "build with $@"
}

echo "Starting args are $@"
cmd=$1
shift

if [ "$cmd" = 'build' ]; then
    build "$@"
fi

1
在调用 build 时应该使用 "$@",但除此之外完全正确。 - Jonathan Leffler

6
function build() {
   make "$@"
}

if [ "$1" == 'build' ]
then shift        # Lose $1
     build "$@"   # Pass what was $2 .. $N
fi

注意在函数本身和调用函数时使用"$@"。我认为很少使用$*$@而不使用双引号"$*"是正确的;只有"$@"保留了原始参数列表的空格,如果您有包含空格的参数,则这一点很重要。 如果您要回显参数,则echo "The arguments: $*"是合理的。 否则,超过90%的时间,最好使用"$@"。 我对测试运算符中的引用"$1"持非常保守的态度; 小心省略引号。
另请参见:

2

除非你想发出更详细的错误消息,否则没有必要显式测试$1。 只需执行:

#!/bin/sh -e
function build() {
   make "$@"
}

"$@"

如果$1是一个有效的函数名,它将按预期调用。如果不是,则会收到错误消息,这可能取决于你的shell而不太糟糕。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接