Können Sie temporäre Dateien bereinigen, bevor sie in der Shell verwendet werden?

Können Sie temporäre Dateien bereinigen, bevor sie in der Shell verwendet werden?

Ich möchte vermeiden, dass temporäre Dateien herumliegen, wenn mein Programm abstürzt.

Das Wunderbare an UNIX ist, dass Sie eine Datei geöffnet lassen können – sogar nachdem Sie sie gelöscht haben.

Wenn Sie die Datei öffnen, löschen Sie sie sofort undDannWenn Sie die langsame Verarbeitung durchführen, ist die Wahrscheinlichkeit hoch, dass der Benutzer die Datei nicht bereinigen muss, selbst wenn Ihr Programm abstürzt.

In der Shell sehe ich oft etwas Ähnliches wie:

generate-the-file -o the-file
[...loads of other stuff that may use stdout or not...]
do_slow_processing < the-file
rm the-file

Wenn das Programm jedoch vorher abstürzt, rmmuss der Benutzer die Bereinigung durchführen the-file.

In Perl können Sie Folgendes tun:

open(my $filehandle, "<", "the-file") || die;
unlink("the-file");
while(<$filehandle>) {
  # Do slow processing stuff here
  print;
}
close $filehandle;

Anschließend wird die Datei sofort nach dem Öffnen entfernt.

Gibt es eine ähnliche Konstruktion in Shell?

Antwort1

Dies wird in csh, tcsh, sh, ksh, zsh, bash, ash, sash getestet:

echo foo > the-file
(rm the-file; cat) < the-file | do_slow_processing
do_other_stuff

oder wenn Sie es vorziehen:

(rm the-file; do_slow_processing) < the-file
do_other_stuff

Interessanterweise funktioniert es auch für FIFOs:

mkfifo the-fifo
(rm the-fifo; cat) < the-fifo | do_slow_processing &
echo foo > the-fifo

Dies liegt daran, dass der Reader blockiert ist, bis etwas geschrieben wird.

Antwort2

generate-the-file > the-file
exec 5< the-file
rm the-file
...
do_slow_processing 0<&5

Anmerkungen:

  • Sie müssen exec ohne ausführbare Datei ausführen, sodass die Deskriptoren der Shell selbst betroffen sind
  • Nur bis FD 9 lieferbar
  • Sie können /proc/self/fd/X verwenden, wenn Sie einen Dateinamen benötigen. Diese Schnittstelle ist nicht zwischen UNIX-Varianten portierbar (bei Ihnen funktioniert sie aber wahrscheinlich).
  • Der Versuch, das fd erneut zu lesen (z. B. zwei Aufrufe von cat 0<&5), schlägt fehl, da Sie sich am EOF befinden. Sie müssen es zurückspulen oder es durch Lesen über überwinden/proc/self/fd/X
  • In den meisten Fällen wie oben können Sie jedoch auf eine tatsächliche Datei verzichten und eine einfachegenerate-the-file | do_slow_processing

Aktualisieren:

Der OP erwähnt, dass generate-the-filedie Ausgabe möglicherweise nicht in stdout erfolgt. Dafür gibt es einige Redewendungen:

  • Geben Sie eine Ausgabedatei von an -. Es ist üblich, einen Ausgabedateinamen von - zu akzeptieren, um stdout zu bedeuten. Dies istbestätigt durch POSIX.1-2017:

    Leitlinie 13: Bei Dienstprogrammen, die Operanden verwenden, um Dateien darzustellen, die zum Lesen oder Schreiben geöffnet werden sollen, sollte der Operand „-“ nur für die Standardeingabe (oder Standardausgabe, wenn aus dem Kontext klar hervorgeht, dass eine Ausgabedatei angegeben wird) oder für eine Datei mit dem Namen „-“ verwendet werden.

(Bei anderen Dienstprogrammen als denen, bei denen dies explizit definiert ist, ist es implementierungsdefiniert, aber es besteht eine gute Chance, dass es von Ihrem generate-the-fileTool unterstützt wird)

Dies funktioniert nicht auf allen Shells und erfordert Betriebssystemunterstützung für FD-Dateinamen.

Antwort3

In der bashShell können Sie die Bereinigung mithilfe des trapintegrierten EXIT-Befehls durchführen (geben Sie innerhalb einer bashShell ein help trap):

trap 'rm temp-file' EXIT

Diese Funktion ist auch in der dashShell vorhanden und wird shin modernen Linux-Distributionen häufig als Alias ​​verwendet.

verwandte Informationen