Sehr oft führen wir eine ausführbare Datei aus, die einige temporäre Dateien schreiben / lesen muss. Normalerweise erstellen wir ein temporäres Verzeichnis, führen die ausführbare Datei dort aus und löschen das Verzeichnis, wenn das Skript fertig ist.
Ich möchte das Verzeichnis löschen, auch wenn die ausführbare Datei beendet ist. Ich habe versucht, es einzuwickeln:
#!/bin/bash
dir=$(mktemp -d /tmp/foo.XXXXXXX) && cd $dir && rm -rf $dir
/usr/local/bin/my_binary
Wenn my_binary
dies stirbt, löscht der Kernel als letztes das Verzeichnis, da das Skript der letzte Prozess ist, der dies enthält inode
. Ich kann jedoch keine Datei im gelöschten Verzeichnis erstellen.
#!/bin/bash
dir=$(mktemp -d /tmp/foo.XXXXXXX) && cd $dir && rm -rf $dir
touch file.txt
Ausgänge touch: file.txt: No such file or directory
Das Beste, was ich mir einfallen lassen kann, ist, das temporäre Verzeichnis zu löschen, wenn der Prozess abbricht, die häufigsten Signale abzufangen und einen Bereinigungsprozess mit cron auszuführen:
#!/bin/bash
dir=$(mktemp -d /tmp/d.XXXXXX) && cd "$dir" || exit 99
trap 'rm -rf "$dir"' EXIT
/usr/local/bin/my_binary
Gibt es eine einfache Möglichkeit, ein wirklich temporäres Verzeichnis zu erstellen, das automatisch gelöscht wird, wenn die aktuelle Binärdatei stirbt, egal was passiert?
cleanup
es ausgeführt werden kann, bevor das Mktemp abgeschlossen ist. Möglicherweise möchten Sie,unset dir
bevor Sie die Falle einstellen.Antworten:
Ihr letztes Beispiel ist das ausfallsicherste.
Dies wird ausgeführt, solange die Shell selbst noch funktionsfähig ist. Grundsätzlich ist SIGKILL das einzige, was es nicht handhaben kann, da die Shell zwangsweise beendet wird.
(Vielleicht hat SIGSEGV es auch nicht versucht, aber es kann gefangen werden)
Wenn Sie es nicht der Shell überlassen, nach sich selbst aufzuräumen, besteht die einzig mögliche Alternative darin, den Kernel dies tun zu lassen. Dies ist normalerweise keine Kernelfunktion, es gibt jedoch einen Trick, den Sie ausführen können, der jedoch seine eigenen Probleme hat:
Grundsätzlich erstellen Sie ein tmpfs-Mount und heben es dann faul auf. Sobald das Skript fertig ist, wird es entfernt.
Der Nachteil, der nicht zu komplex ist, ist, dass Sie kein Mount herumliegen haben, wenn das Skript aus irgendeinem Grund vor dem Unmount stirbt.
Dies verwendet auch tmpfs, die Speicher verbrauchen. Sie können den Prozess jedoch komplexer gestalten, ein Loop-Dateisystem verwenden und die Datei entfernen, die ihn nach dem Mounten sichert.
Letztendlich
trap
ist das Beste in Bezug auf Einfachheit und Sicherheit, und wenn Ihr Skript nicht regelmäßig SIGKILLed wird, würde ich dabei bleiben.quelle
mktemp
oder danach platziert wird? Ich würde denken, wenn die Falle direkt vor der platziert wirdmktemp
, dann würde, selbst wenn das Ausgangssignal nach der Falle und vor der empfangenmktemp
würde, nur einrm -rf
Befehl mit einem leeren Argument ausgeführt, der nichts bewirkt. Aber wenn die Falle nach dem wäremktemp
, könnte es ein winziges Fenster geben, in dem die Chance besteht, dass das temporäre Verzeichnis verlassen wird. Oder bin ich völlig aus der Basis?Mit der integrierten Wartezeit können Sie warten, bis ein Hintergrundjob abgeschlossen ist:
quelle
blah; rm -rf $DIR
, oder? Es hat das Problem, dass $ DIR ausläuft, wenn das Skript beendet wird.