Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何调用提供存储在bash数组中的环境变量的bash函数?_Bash - Fatal编程技术网

如何调用提供存储在bash数组中的环境变量的bash函数?

如何调用提供存储在bash数组中的环境变量的bash函数?,bash,Bash,我在bash脚本中得到了两个变量。一个包含脚本中函数的名称,而另一个是包含KEY=VALUE或KEY='VALUE WITH SPACES'对的数组。它们是解析特定文件的结果,我无法更改 我想做的是调用我得到的函数名。这很简单: # get the value for the function myfunc="some_function" # invoke the function whose name is stored in $myfunc $myfunc 将函数foo定义为 functi

我在bash脚本中得到了两个变量。一个包含脚本中函数的名称,而另一个是包含
KEY=VALUE
KEY='VALUE WITH SPACES'
对的数组。它们是解析特定文件的结果,我无法更改

我想做的是调用我得到的函数名。这很简单:

# get the value for the function
myfunc="some_function"
# invoke the function whose name is stored in $myfunc
$myfunc
将函数
foo
定义为

function foo
{
   echo "MYVAR: $MYVAR"
   echo "MYVAR2: $MYVAR2" 
}
如果我得到变量

funcname="foo"
declare -a funcenv=(MYVAR=test "MYVAR2='test2 test3'")
如何使用它们调用
foo
,并将
funcev
对添加到环境中?(非变量)调用如下所示

MYVAR=test MYVAR2='tes2 test3' foo
我试着把它写成

"${funcenv[@]}" "$funcname"
但这会导致错误(
MYVAR=test:command not found


如何将数组的参数放在函数的环境中正确调用函数(我不想导出它们,它们应该只对调用的函数可用)?

为什么不将它们作为参数传递给函数

function f() { echo "first: $1";  echo "second: $2"; }

fn=f; $fn oneword "two words"
您可以这样做:

declare -a funcenv=(MYVAR=test "MYVAR2='test2 test3'")
for pairs in "${funcenv[@]}"; do
    eval "$pairs"
done
"$funcname"
但是请注意,变量也将在函数外部可见。
如果您想避免这种情况,那么您可以将上述所有内容封装在
(…)
子shell中。

您需要使用
eval
来执行动态构建的代码。您需要
eval
来执行此操作的事实应该被视为系统中的一个主要设计缺陷,这应该是固定的。因为我已经向它传递了参数(为了简单起见,省略了它),我确实需要区分参数和“第二类参数”,并且还需要某种散列,这两种类型的散列都会提供使用
declare
可能比使用
eval
更安全。如果没有其他内容,它会记录您正在定义变量,而不是执行任意代码。(尽管这需要在数组中使用不带单引号的
MYVAR2=test2 test3
)@chepner我认为需要邪恶的
eval
来计算表达式,因为它可能嵌入了引号。(OP说数组内容是给定的,不可能更改)@janos是的,我意识到在我第一次评论之后,添加了括号来解决这个问题。理想情况下,我知道OP说他们不能改变它,配置会改变,因为依赖
eval
的配置系统最脆弱。比较
eval“foo='12'”
声明“foo=12”
;两者都声明
foo
的值为
12
。将引号从
eval
中去掉,尝试在其环境中使用
foo=1运行名为
2
的命令时会出现错误。将引号添加到
declare
,引号是
foo
值的一部分。没有一种方法可以兼顾两者;它们的行为完全不同。
declare
优于
eval
的好处可以通过比较来看出,例如,
eval'foo=$(echo hi)
declare'foo=$(echo hi)
eval
执行命令替换<代码>声明
没有。