如何传递给 bash 函数 2 可变参数列表?

How to pass to bash function 2 variadic argument lists?

我正在寻找一种抽象通用命令的方法:

find src app -name "*.hs" -exec grep -H "foo" \{\} \;

到 bash/zsh 函数,例如:

find -exec grep -H \{\} \;

以上不是解决方案,因为我想传递参数列表,例如使用给定语法:findgrep "src -name '.hs'" "foo"。 在这里我们可以说 grep 的参数实际上是一个单词,然后将参数列表的其余部分传递给 find 但应该有更通用的方法吗?有没有办法部分应用 bash 函数?

提前致谢!

一般来说,您不能这样做,因为每个单独的参数都只是一个常规字符串; shell 没有明确的列表类型。

要传递两个“组”参数,您需要定义某种您的函数可以识别的“哨兵”。例如,

findgrep () {
    args=()
    for x; do
        shift
        [[ $x == ::: ]] && break
        args+=("$x")
    done
    find "${args[@]}" -exec grep -H "$@" {} \;
}

findgrep src -name ".hs" ::: foo

findgrep 将向数组 args 添加参数,直到它看到参数 :::,此时它将忽略 ::: 但停止迭代。现在您可以使用 args 作为 find 的第一组参数,而 $@ 中剩余的任何内容作为第二组。

找到一个有效的哨兵可能很困难,因为实际上没有任何字符串在理论上不能成为 find 的有效参数。另一种方法是使用 agreed-upon 全局数组来存储一个或两个集合。

findgrep () {
    find "${findgrepargs[@]}" -exec grep -H "$@" {} \;
}

findgrepargs=(src -name .hs)
findgrep foo

或者使用 nameref 将任意数组的名称传递给函数。

findgrep () {
    declare -n findargs=
    shift
    findgrep "${findargs[@]}" -exec grep -H "$@" {} \;
}

x=(src -name .hs)
findgrep x foo