Frage

Ich temporäre Dateien von einem Bash-Skript. Ich bin sie am Ende der Verarbeitung zu löschen, aber da das Skript für eine recht lange Zeit läuft, wenn ich es töten oder einfach STRG + C während des Laufs werden die temporären Dateien nicht gelöscht.
Gibt es eine Weise, die ich diese Ereignisse und clean-up die Dateien fangen, bevor die Ausführung endet?

Auch ist es eine Art Best Practice für die Benennung und Ort dieser temporären Dateien?
Ich bin zur Zeit nicht sicher, ob zwischen der Verwendung:

TMP1=`mktemp -p /tmp`
TMP2=`mktemp -p /tmp`
...

und

TMP1=/tmp/`basename $0`1.$$
TMP2=/tmp/`basename $0`2.$$
...

Vielleicht gibt es einige bessere Lösungen?

War es hilfreich?

Lösung

Sie könnten einen " Trap " gesetzt auszuführen auf verlassen oder auf einem Steuer-c aufzuräumen.

trap "{ rm -f $LOCKFILE; }" EXIT

Alternativ einer meiner Lieblings-Unix-isms ist eine Datei zu öffnen, und löschen Sie sie dann, während Sie noch offen haben. Die Datei bleibt auf dem Dateisystem und Sie können sie lesen und schreiben, aber sobald das Programm beendet wird, geht die Datei entfernt. Nicht sicher, wie Sie, dass in der Bash tun würden, wenn.

BTW: Ein Argument, das ich für mktemp geben werde, anstatt eine eigene Lösung zu verwenden: wenn der Benutzer das Programm rechnet riesige temporäre Dateien erstellen wird, stellte er TMPDIR irgendwo größer wollen könnte, wie / var / tmp . mktemp erkennt an, dass Ihre handgerollte Lösung (zweite Option) nicht. Ich häufig benutze TMPDIR=/var/tmp gvim -d foo bar, zum Beispiel.

Andere Tipps

Ich schaffe in der Regel ein Verzeichnis, in dem alle meine temporäre Dateien zu platzieren, und dann unmittelbar nach dem Erstellen eines EXIT-Handler dieses Verzeichnis zu bereinigen, wenn das Skript beendet.

MYTMPDIR=$(mktemp -d)
trap "rm -rf $MYTMPDIR" EXIT

Wenn Sie alle temporären Dateien unter $MYTMPDIR setzen, dann werden sie alle gelöscht werden, wenn das Skript in den meisten Fällen tritt aus. Das Töten eines Prozesses mit SIGKILL (kill -9) tötet, obwohl der Prozess sofort, so dass Ihre EXIT-Handler in diesem Fall nicht ausgeführt wird.

Sie möchten die Trap Befehl Beenden des Skripts oder Signale wie CTRL-C zu handhaben. Finden Sie in der Gregs Wiki .

Für Ihre tempfiles, basename $0 ist eine gute Idee, sowie die Bereitstellung einer Vorlage, die Raum für genügend temporäre Dateien lautet:

tempfile() {
    tempprefix=$(basename "$0")
    mktemp /tmp/${tempprefix}.XXXXXX
}

TMP1=$(tempfile)
TMP2=$(tempfile)

trap 'rm -f $TMP1 $TMP2' EXIT

Denken Sie daran, die Antwort gewählt ist bashism, die Lösung als

bedeutet,
trap "{ rm -f $LOCKFILE }" EXIT

würde nur in bash arbeiten (es wird Ctrl nicht fangen + c, wenn Shell ist dash oder klassische sh), aber wenn Sie Kompatibilität wollen, dann müssen Sie noch alle Signale aufzuzählen, die Sie zu stoppen wollen.

Denken Sie auch daran, dass, wenn Skript beendet die Falle für Signal „0“ (auch bekannt als EXIT) erfolgt immer in doppelter Ausführung trap Befehls zur Folge hat.

Das ist der Grund nicht alle Signale in einer Zeile zu stapeln, wenn EXIT-Signal ist.

Um besser zu verstehen, ist es in der folgenden Skript suchen, die über verschiedene Systeme hinweg ohne Änderungen funktionieren:

#!/bin/sh

on_exit() {
  echo 'Cleaning up...(remove tmp files, etc)'
}

on_preExit() {
  echo
  echo 'Exiting...' # Runs just before actual exit,
                    # shell will execute EXIT(0) after finishing this function
                    # that we hook also in on_exit function
  exit 2
}


trap on_exit EXIT                           # EXIT = 0
trap on_preExit HUP INT QUIT TERM STOP PWR  # 1 2 3 15 30


sleep 3 # some actual code...

exit 

Diese Lösung wird Ihnen mehr Kontrolle geben, da Sie einige Ihrer Code auf das Auftreten von Ist-Signal kurz vor dem endgültigen Ausgang (preExit Funktion) laufen kann, und wenn es benötigt wird, kann man einen Code zu Ist-EXIT-Signal (Endstadium der Ausfahrt) laufen

Die Alternative einer vorhersagbaren Dateinamen mit $$ eine klaffende Sicherheitslücke ist, und Sie sollten nie, nie, nie darüber nachdenken, es zu benutzen. Auch wenn es nur eine einfache persönliche Skript auf Ihrem Single-User-PC ist. Es ist eine sehr schlechte Gewohnheit, die Sie nicht erhalten sollen. BugTraq ist voll von „unsichere temporäre Datei“ Vorfälle. Siehe hier , hier und hier für weitere Informationen über den Sicherheitsaspekt von temporären Dateien.

Ich war am Anfang des Denkens, die unsicher TMP1 und TMP2 Zuweisungen zu zitieren, aber auf den zweiten Gedanken das wäre wahrscheinlich keine gute Idee sein.

Ich ziehe mit tempfile, die eine Datei in / tmp in die sichere Weise erstellt und Sie müssen sich keine Gedanken über seine Benennung Sorge:

tmp=$(tempfile -s "your_sufix")
trap "rm -f '$tmp'" exit

Sie müssen nicht die Mühe machen, diese tmp-Dateien mit mktemp erstellt entfernen. Sie werden später gelöscht sowieso werden.

Mit mktemp, wenn Sie können, da es mehr eindeutige Dateien erzeugt dann ‚$$‘ prefix. Und es sieht aus wie Art und Weise mehr Cross-Plattform-Temp-Dateien erstellen sie dann explizit in / tmp gesetzt.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top