Come eliminare automaticamente una directory quando viene ucciso un eseguibile


9

Molto spesso, eseguiamo un eseguibile che deve scrivere / leggere alcuni file temporanei. Generalmente creiamo una directory temporanea, eseguiamo lì l'eseguibile ed eliminiamo la directory quando lo script è terminato.

Voglio eliminare la directory anche se l'eseguibile viene ucciso. Ho cercato di avvolgerlo in:

#!/bin/bash
dir=$(mktemp -d /tmp/foo.XXXXXXX) && cd $dir && rm -rf $dir
/usr/local/bin/my_binary

Quando my_binarymuore, l'ultimo processo il kernel eliminerà la directory, poiché lo script è l'ultimo processo che lo tiene inode; ma non riesco a creare alcun file nella directory eliminata.

#!/bin/bash
dir=$(mktemp -d /tmp/foo.XXXXXXX) && cd $dir && rm -rf $dir
touch file.txt

uscite touch: file.txt: No such file or directory

Il meglio che potrei trovare è eliminare la directory temporanea quando il processo termina, catturando i segnali più comuni ed eseguire un processo di pulizia con cron:

#!/bin/bash
dir=$(mktemp -d /tmp/d.XXXXXX) && cd "$dir" || exit 99
trap 'rm -rf "$dir"' EXIT
/usr/local/bin/my_binary

Esiste un modo semplice per creare una directory davvero temporanea che viene eliminata automaticamente quando il file binario attuale muore, non importa quale?


1
attenzione che si dispone di una piccola finestra in cui cleanuppuò essere eseguita prima che mktemp sia terminato. Potrebbe essere necessario unset dirprima di impostare la trappola.
Stéphane Chazelas,

bella cattura, ho aggiornato lo script per gestire questo e per gestire un errore in mktemp.
Joaquin Cuenca Abela,

Ho pensato che l'uscita fosse obbligatoria. Fisso.
Joaquin Cuenca Abela,

Il tuo ultimo esempio menziona cron, ma non ha nulla a che fare con cron. Quell'ultimo esempio è anche il più sicuro. L'unica cosa che non gestirà è SIGKILL.
Patrick,

Non ho incluso lo script cron che sto eseguendo per mantenerlo succint. È una ricerca su quel modello per abbinare dirs più vecchi di 1 ora e rm loro. Voglio sapere se esiste una soluzione che coprirà anche il caso sigkill, o anche un arresto brutale nel mezzo della sceneggiatura.
Joaquin Cuenca Abela,

Risposte:


3

Il tuo ultimo esempio è il più sicuro.

trap 'rm -rf "$dir"' EXIT

Questo verrà eseguito fintanto che la shell stessa sarà ancora funzionale. Fondamentalmente SIGKILL è l'unica cosa che non gestirà poiché la shell è forzatamente terminata.
(forse anche SIGSEGV, non ha provato, ma può essere catturato)

Se non lo lasci alla shell per ripulire dopo se stesso, l'unica altra alternativa possibile è che il kernel lo faccia. Questa non è normalmente una funzionalità del kernel, tuttavia c'è un trucco che puoi fare, ma ha i suoi problemi:

#!/bin/bash
mkdir /tmp/$$
mount -t tmpfs none /tmp/$$
cd /tmp/$$
umount -l /tmp/$$
rmdir /tmp/$$

do_stuff

Fondamentalmente crei un mount tmpfs e poi pigri smontalo. Una volta fatto, lo script verrà rimosso.
Il rovescio della medaglia, oltre ad essere eccessivamente complesso, è che se lo script muore per qualsiasi motivo prima dello smontaggio, non c'è un supporto in giro.
Questo utilizza anche tmpfs, che consumerà memoria. Ma potresti rendere il processo più complesso e utilizzare un filesystem loop e rimuovere il file che lo supporta dopo che è stato montato.


Alla fine trapè la cosa migliore in termini di semplicità e sicurezza e, a meno che la tua sceneggiatura non riceva regolarmente SIGKILL, resterei fedele.


Importa se la trappola viene posizionata prima mktempo dopo? Penserei che se la trappola fosse posizionata appena prima di mktemp, quindi anche se il segnale di uscita fosse ricevuto dopo la trappola e prima di mktemp, tutto ciò che accadrebbe sarebbe un rm -rfcomando eseguito con un argomento vuoto, senza ottenere nulla. Ma se la trappola fosse dietro la mktemp, ci potrebbe essere una piccola finestra sulla possibilità che la directory temporanea venga lasciata. O sono completamente fuori base?
Wildcard il

1

È possibile utilizzare l' attesa integrata per attendere il completamento di un processo in background:

blah &
wait
rm -rf $DIR

Ma sarà equivalente a blah; rm -rf $DIR, giusto? Ha il problema che perderà $ DIR se lo script viene ucciso.
Joaquin Cuenca Abela,

Se lo script figlio viene ucciso, lo script padre sarà comunque in giro per ripulirlo. Se anche lo script genitore viene ucciso, sì, la directory verrà lasciata indietro.
Matthew Cline,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.