4

我需要在 C/C++ 程序的 Bash 环境中定义一个 Bash 函数。在shellshock错误之前,我可以这样定义一个函数:

my_func='() { echo "This is my function";}'

或来自 C 程序的等价物:

setenv("my_func", "() { echo \"This is my function\";}", 1);

或者

putenv("my_func=() { echo \"This is my function\";}");

但是使用修复了shellshock的 Bash 版本,我无法管理如何在环境中定义我的函数。

奇怪的是,如果我运行env,我可以看到我在环境中定义的函数,但如果我调用它,Bash 说它不存在。

提前致谢

4

2 回答 2

7

仅供参考。由于没有记录函数是如何导出到环境中的,因此您应该将其视为对私有 API 的滥用,该 API 在未来版本的bash.

不再仅使用环境字符串中的函数名称导出函数。要看到这个,运行

$ my_func () { echo "foo"; }
$ export -f my_func
$ env | grep -A1 'my_func'
BASH_FUNC_my_func%%=() {  echo "foo"
}

由于环境中使用的名称不再是有效bash标识符,因此您需要使用该env命令来修改新进程的环境。

env 'BASH_FUNC_my_func%%=() { echo "This is my function"; }' bash

从C开始,只需要调整名称即可。​​​​​​</p>

setenv("BASH_FUNC_my_func%%", "() { echo \"This is my function\";}", 1);
于 2014-10-10T13:20:51.310 回答
2

如果您正在调用bashexecv以便您只调用一次),您可以替换(execl用于解释目的):

 execl("/bin/bash", "bash", "file_to_run", "arg1", "arg2", 0);

 execl("/bin/bash", "bash", "-c", "f() {...} g() {...}\n. $0",
                    "file_to_run", "arg1", "arg2", 0);

然后你就不需要用内部 bash 接口来玩游戏来定义函数了。(如果正在运行的 bash 脚本也需要导出函数,无论出于何种原因,只需在.export -f <func>后面的参数中添加行-c。)

这具有同时使用已修补和未修补的 bash 的优势。

(我不得不为各种程序制作类似的补丁,所以我分享你的痛苦。)

于 2014-10-10T16:11:46.797 回答