Generalmente, n. Questo non è possibile per la ragione che hai menzionato.
Questa è una risposta noiosa però. Diamo un'occhiata alle nostre opzioni per soluzioni alternative:
Se ci preoccupiamo di più sulla semantica exec e meno su come avviare processi multipli, possiamo per gli eseguibili arbitrari fare:
{ while kill -0 $$; do sleep 5; done; rm "$0.$$"; } &
exec ./file
che exec
il file e hanno un altro polling processo e facendo pulizia quando ha finito.
Se vogliamo evitare forchette e quello che stiamo eseguendo è un altro script di shell, possiamo fare
exec bash --rcfile <(echo 'trap "..." exit') -i ./file
al exec
il file e fare la pulizia dopo (finché lo script non fa exec
o scavalcare la trappola), senza avviare un nuovo processo. source
ing invece di exec
ing avrà più o meno lo stesso effetto:
trap "..." exit
source ./file
Se vogliamo ottenere davvero hacky, possiamo usare LD_PRELOAD
per ignorare exit(3)
ed eseguire un comando di nostra scelta:
#include <stdlib.h>
void exit(int c) {
char* cmd = getenv("EXIT");
char *argv[] = { "bash", "-c", cmd, NULL };
char *envp[] = { NULL };
execvpe("bash", argv, envp);
}
Possiamo compilarlo come una libreria:
$ gcc -shared -fPIC foo.c -o libfoo.so
e quindi precaricare in executa arbitrario, collegato dinamicamente bles:
$ LD_PRELOAD=./libfoo.so EXIT='echo "This is a hack"' ls *foo*
foo.c libfoo.so
This is a hack
Questi hack sono divertenti, ma raramente necessari nel mondo reale. La soluzione più semplice, migliore e più canonica è semplicemente non exec
.