2014-06-08 9 views
10

Chciałbym użyć bash EXIT pułapki i użyć exec, aby uniknąć pojawienia się nowego procesu. czy to możliwe?Jak mogę uzyskać pułapkę basha EXIT podczas wykonywania innego pliku binarnego?

Oznacza to,

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

usuwa plik tymczasowy $0.$$ korzystając atakujących za EXIT pułapkę podczas

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

nie "odpala" pułapka (żadna wiadomość od rm, sygn $0.$$ istnieje po zakończeniu).

To oczywiście ma sens, że pułapka nie może wystrzelić, ponieważ bash nie ma już kontroli po exec. Czy jest jakiś sposób, aby to zadziałało i użyć exec? Jest to niewątpliwie z ciekawości bardziej niż praktyczne.

Odpowiedz

12

Generalnie nie. Nie jest to możliwe z tego powodu, o którym wspomniałeś.

To jednak nudna odpowiedź. Spójrzmy na nasze opcje do obejścia:

Jeśli dbamy bardziej o semantykę exec i mniej o rozpoczęciu wiele procesów, możemy do zrobić dowolne pliki wykonywalne:

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

które exec plik i mieć inny odpytywanie procesu i czyszczenie po zakończeniu.

Jeśli chcemy uniknąć widelce i co mamy do wykonania nie jest w inny skrypt, możemy zrobić

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

do exec plik i zrobić porządki potem (o ile skrypt nie exec lub zastąpić pułapkę), bez rozpoczynania nowego procesu. source ing zamiast exec ING będzie mieć dużo ten sam efekt:

trap "..." exit 
source ./file 

Jeśli chcemy uzyskać naprawdę hacky, możemy użyć LD_PRELOAD przesłonić exit(3) i uruchomić polecenie naszego wyboru:

#include <stdlib.h> 

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

Możemy skompilować to jako bibliotekę:

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

a następnie załaduj ją do dowolnego, dynamicznie połączonego executa bles:

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

Te hacki są zabawne, ale rzadko niezbędne w realnym świecie. Prostsze, lepsze i bardziej kanoniczne rozwiązanie jest po prostu nie exec.

Powiązane problemy