我正在尝试创建一个创建函数的函数。我想根据传递到外部函数的内容对内部函数中的参数进行“硬编码”,例如
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; }" ); }