gpt4 book ai didi

bash - 执行另一个二进制文件时如何实现 bash EXIT 陷阱?

转载 作者:行者123 更新时间:2023-11-29 08:45:04 30 4
gpt4 key购买 nike

我想使用 bash EXIT 陷阱使用exec 来避免生成新进程。这可能吗?

也就是说,

#!/bin/bash
touch $0.$$
trap "rm -v $0.$$" EXIT
/bin/echo Hello

使用 bash 的 EXIT 陷阱删除临时文件 $0.$$

#!/bin/bash
touch $0.$$
trap "rm -v $0.$$" EXIT
exec /bin/echo Hello

从不“触发”陷阱(没有来自 rm 的消息,完成后文件 $0.$$ 存在)。

当然,陷阱无法触发是有道理的,因为在 exec 之后 bash 不再受控制。有没有办法让它工作并且使用exec?诚然,这更多是出于好奇而非实际问题。

最佳答案

一般不会。由于您提到的原因,这是不可能的。

虽然这是一个无聊的答案。让我们看看解决方法的选项:

如果我们更关心 exec 语义而不是启动多个进程,我们可以为任意可执行文件做:

{ while kill -0 $$; do sleep 5; done; rm "$0.$$"; } &
exec ./file

这将执行文件并让另一个进程轮询它并在完成后进行清理。

如果我们想避免 fork 并且我们正在执行的是另一个 shell 脚本,我们可以这样做

exec bash --rcfile <(echo 'trap "..." exit') -i ./file

exec 文件并在之后进行清理(只要脚本不exec 或覆盖陷阱),而不启动新进程。 sourceing 而不是 execing 将产生几乎相同的效果:

trap "..." exit
source ./file

如果我们想要真正 hacky,我们可以使用 LD_PRELOAD 覆盖 exit(3) 并运行我们选择的命令:

#include <stdlib.h>

void exit(int c) {
char* cmd = getenv("EXIT");
char *argv[] = { "bash", "-c", cmd, NULL };
char *envp[] = { NULL };
execvpe("bash", argv, envp);
}

我们可以把它编译成一个库:

$ gcc -shared -fPIC foo.c -o libfoo.so

然后将其预加载到任意动态链接的可执行文件中:

$ LD_PRELOAD=./libfoo.so EXIT='echo "This is a hack"' ls *foo*
foo.c libfoo.so
This is a hack

这些 hack 很有趣,但在现实世界中很少需要。更简单、更好和更规范的解决方案就是不执行 exec

关于bash - 执行另一个二进制文件时如何实现 bash EXIT 陷阱?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24111981/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com