Bash 函数内部函数:如何从外部函数插入某些变量

Bash 函数内部函数:如何从外部函数插入某些变量

我正在尝试创建一个创建函数的函数。我想根据传递到外部函数的内容对内部函数中的参数进行“硬编码”,例如

outer() {
    inner() { doSomething --context=$1 $@ }
}

鉴于上述情况,在致电时

outer foo

我希望内部函数的定义就像我运行的一样

inner() { doSomething --context=foo $@ }

换句话说,在内部函数的定义中插入外部函数的 $1,但在调用内部函数时保留 $@ 进行插入。

我怎样才能实现这个目标?


编辑,对于那些想知道我的用例的人:

我正在使用带有子命令的命令行工具,例如

doSomething dothis somearg
doSomething dothat

但它总是需要一个上下文标志,例如

doSomething --context foo dothis somearg
doSomething --context foo dothat

通常,一旦进入上下文,接下来的几个命令将使用相同的上下文。

因此,理想的解决方案允许我设置一次上下文并使用内部函数,就像已经知道其上下文的别名一样:

outer foo
inner dothis somearg
inner dothat

这也可以通过环境变量来完成,例如

alias inner="doSomething --context=$CONTEXT"

但实际上有 2 个标志而不是 1 个,而这个(现在有了现实的参数)——

outer gke_gke-xpn-1_europe-west1_europe-west1-s41l stats_service
inner dothis somearg
inner dothat

——(对我来说)比——使用起来更友好一些

CONTEXT=gke_gke-xpn-1_europe-west1_europe-west1-s41l
NAMESPACE=stats_service
inner dothis somearg
inner dothat

答案1

我正在尝试创建一个创建函数的函数。我想根据传递到外部函数的内容对内部函数中的参数进行“硬编码”,

你想要的是一个闭包,而我认为 Bash 中没有这样的闭包。

只需使用另一个全局变量作为内部函数运行的“上下文”。例如

context=
outer() {
    context=$1
}
inner() {
    if [ -z "$context" ]; then
        echo "context not defined" >&2
        return 1;
    fi
    doSomething --context="$context" "$@"
}

如果您需要两个上下文变量,只需添加另一个即可。

请注意,您应该引用两者"$context",并"$@"确保带有空格或通配符的值不会因分词而被破坏。

答案2

好吧,经过一个小时的修修补补,我实际上已经弄清楚了。关键是使用eval和转义应该延迟插值的变量。如果有更好的方法,我想知道!所以请添加一个答案。

#!/bin/bash
outer() {
    eval "inner() { doSomething --context=$1 \$@ }"
}

答案3

这就是 bash 中的实现方式:

#!/bin/bash
outer() {
    # define inner function
    inner() {
        echo 1=$1 2=$2 
    }

    # call inner function
    inner $1 $2
}

# this would give an error, 
inner foo 123

# call outer function.
outer bar 456

# now the inner function is defined and ready to be used by itself
inner baz 789

答案4

在 中bash,这有效:

outer() { . <( echo "inner() { doSomething $1 $2;  }" ); }

相关内容