How can I achieve bash EXIT trap when exec-ing another binary?

后端 未结 1 1488
挽巷
挽巷 2021-02-07 01:54

I\'d like to use a bash EXIT trap and use exec to avoid spawning a new process. Is this possible?

That is,

#!/bin/bas         


        
相关标签:
1条回答
  • 2021-02-07 02:31

    Generally, no. This is not possible for the reason you mention.

    That's a boring answer though. Let's look at our options for workarounds:

    If we care more about exec semantics and less about starting multiple processes, we can for arbitrary executables do:

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

    which will exec the file and have another process polling it and doing cleanup when it's done.

    If we want to avoid forks and what we're executing is another shell script, we can do

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

    to exec the file and do the cleanup afterwards (as long as the script doesn't exec or override the trap), without starting a new process. sourceing instead of execing will have much the same effect:

    trap "..." exit
    source ./file
    

    If we want to get really hacky, we can use LD_PRELOAD to override exit(3) and run a command of our choice:

    #include <stdlib.h>
    
    void exit(int c) {
        char* cmd = getenv("EXIT");
        char *argv[] = { "bash", "-c", cmd, NULL };
        char *envp[] = { NULL };
        execvpe("bash", argv, envp);
    }
    

    We can compile this as a library:

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

    and then preload it into arbitrary, dynamically linked executables:

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

    These hacks are fun, but rarely necessary in the real world. The simpler, better and more canonical solution is just to not exec.

    0 讨论(0)
提交回复
热议问题