2014-06-08 8 views
10

Ich möchte eine Bash EXIT Trap und Verwendung exec verwenden, um zu vermeiden, einen neuen Prozess zu erzeugen. Ist das möglich?Wie kann ich bash EXIT Trap erreichen, wenn ich eine andere Binärdatei ausführe?

Das heißt,

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

entfernt die temporäre Datei $0.$$EXIT Falle der Verwendung von bash während

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

nie "Feuer" die Falle (keine Meldung von rm, Datei $0.$$ nach Abschluss vorhanden ist).

Es macht natürlich Sinn, dass die Falle nicht feuern kann, da bash nach der exec nicht mehr die Kontrolle hat. Gibt es einen Weg, es zum Laufen zu bringen und Gebrauch exec? Dies ist zugegebenermaßen mehr aus Neugier als aus praktischen Gründen.

Antwort

12

Im Allgemeinen keine. Dies ist aus dem von Ihnen genannten Grund nicht möglich.

Das ist eine langweilige Antwort. Lassen Sie uns für Abhilfen unsere Optionen aussehen:

Wenn wir mehr über exec Semantik und weniger über mehrere Prozesse starten kümmern, können wir für beliebige ausführbare Dateien tun:

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

, die die Datei exec und einen anderen Prozess Polling haben es und Aufräumen, wenn es fertig ist.

Wenn wir Gabeln vermeiden wollen und was wir Ausführung ist ein weiterer Shell-Skript, können wir

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

zu exec die Datei tun und danach die Bereinigung tun (solange das Skript nicht exec oder überschreiben Sie die Falle, ohne einen neuen Prozess zu starten. source statt exec ing ing wird den gleichen Effekt haben:

trap "..." exit 
source ./file 

Wenn wir wirklich Hacky erhalten möchten, wir LD_PRELOADexit(3) außer Kraft setzen können und einen Befehl unserer Wahl ausführen:

#include <stdlib.h> 

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

Wir können dies als eine Bibliothek kompilieren:

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

und dann laden Sie es in beliebige, dynamisch verknüpfte Executa Bles:

Diese Hacks sind Spaß, aber selten in der realen Welt notwendig. Die einfachere, bessere und kanonischere Lösung ist einfach nicht zu exec.