一般来说,没有。由于您提到的原因,这是不可能的。
虽然这是一个无聊的答案。让我们看看我们的解决方法选项:
如果我们更关心 exec 语义而不是启动多个进程,我们可以对任意可执行文件执行以下操作:
{ while kill -0 $$; do sleep 5; done; rm "$0.$$"; } &
exec ./file
这将exec
文件并有另一个进程轮询它并在完成后进行清理。
如果我们想避免分叉并且我们正在执行的是另一个 shell 脚本,我们可以这样做
exec bash --rcfile <(echo 'trap "..." exit') -i ./file
到exec
文件并在之后进行清理(只要脚本没有exec
或覆盖陷阱),而不启动新进程。source
ing 而不是exec
ing 将产生相同的效果:
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
这些技巧很有趣,但在现实世界中很少需要。更简单、更好和更规范的解决方案就是不exec
。