在环境中设置Bash功能

Jos*_*ura 4 linux bash environment-variables setenv shellshock-bash-bug

我需要从C/C++程序在Bash环境中定义一个Bash函数.在shellshock bug 之前,我可以用这种方式定义一个函数:

my_func='() { echo "This is my function";}'
Run Code Online (Sandbox Code Playgroud)

或等同于C程序:

setenv("my_func", "() { echo \"This is my function\";}", 1);
Run Code Online (Sandbox Code Playgroud)

要么

putenv("my_func=() { echo \"This is my function\";}");
Run Code Online (Sandbox Code Playgroud)

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

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

提前致谢

che*_*ner 7

仅供参考.由于没有记录如何将函数导出到环境中,因此您应该将其视为滥用私有API,该API在将来的版本中可能会发生变化bash.

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

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

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

env 'BASH_FUNC_my_func%%=() { echo "This is my function"; }' bash
Run Code Online (Sandbox Code Playgroud)

从C,您只需要调整名称.

setenv("BASH_FUNC_my_func%%", "() { echo \"This is my function\";}", 1);
Run Code Online (Sandbox Code Playgroud)


ric*_*ici 2

如果您调用bashwith execv(这样您只调用它一次),您可以替换(用于execl解释目的):

 execl("/bin/bash", "bash", "file_to_run", "arg1", "arg2", 0);
Run Code Online (Sandbox Code Playgroud)

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

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

这样做的优点是可以同时使用修补过的和未修补过的 bash。

(我必须为各种程序制作类似的补丁,所以我分担你的痛苦。)