Rhy*_*ich 20 bash exec bash-trap
我想使用bash EXIT
陷阱并使用exec
以避免产生新进程.这可能吗?
那是,
#!/bin/bash
touch $0.$$
trap "rm -v $0.$$" EXIT
/bin/echo Hello
Run Code Online (Sandbox Code Playgroud)
$0.$$
使用bash的EXIT
陷阱删除临时文件
#!/bin/bash
touch $0.$$
trap "rm -v $0.$$" EXIT
exec /bin/echo Hello
Run Code Online (Sandbox Code Playgroud)
永远不会"触发"陷阱(完成后没有来自rm
文件的消息$0.$$
).
当然,它是有道理的,陷阱不会发射,因为bash不再受到控制exec
.有没有办法让它工作和使用exec
?诚然,这不仅仅是出于好奇而不是实际问题.
tha*_*guy 22
一般来说,没有.你提到的原因是不可能的.
这是一个无聊的答案.我们来看看解决方法的选项:
如果我们更关心exec语义而不是关于启动多个进程,我们可以为任意可执行文件做:
{ while kill -0 $$; do sleep 5; done; rm "$0.$$"; } &
exec ./file
Run Code Online (Sandbox Code Playgroud)
该exec
文件将由另一个进程轮询并在完成后进行清理.
如果我们想要避免分叉,我们正在执行的是另一个shell脚本,我们可以做到
exec bash --rcfile <(echo 'trap "..." exit') -i ./file
Run Code Online (Sandbox Code Playgroud)
到exec
文件并在之后进行清理(只要脚本没有exec
或覆盖陷阱),而不启动新进程.source
而不是exec
ing会产生同样的效果:
trap "..." exit
source ./file
Run Code Online (Sandbox Code Playgroud)
如果我们想要变得非常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);
}
Run Code Online (Sandbox Code Playgroud)
我们可以将其编译为库:
$ gcc -shared -fPIC foo.c -o libfoo.so
Run Code Online (Sandbox Code Playgroud)
然后将其预加载到任意动态链接的可执行文件中:
$ LD_PRELOAD=./libfoo.so EXIT='echo "This is a hack"' ls *foo*
foo.c libfoo.so
This is a hack
Run Code Online (Sandbox Code Playgroud)
这些黑客很有趣,但在现实世界中很少需要.更简单,更好,更规范的解决方案就是不exec
.
归档时间: |
|
查看次数: |
3727 次 |
最近记录: |