Shell-Skript zum Entfernen einer Datei, falls diese bereits vorhanden ist

183

Ich arbeite an einigen Dingen, bei denen ich Daten in einer Datei speichere. Aber jedes Mal, wenn ich das Skript ausführe, wird es an die vorherige Datei angehängt.

Ich möchte Hilfe, wie ich die Datei entfernen kann, wenn sie bereits vorhanden ist.

Niks
quelle
3
Überprüfen Sie, ob die Datei vorhanden ist ... und rufen Sie dann an rm $my_file, oder? Welche Shell benutzt du?
Chris Sprague

Antworten:

181

Überprüfen Sie nicht, ob die Datei vorhanden ist, sondern entfernen Sie sie.

rm -f /p/a/t/h
# or
rm /p/a/t/h 2> /dev/null

Beachten Sie, dass der zweite Befehl fehlschlägt (einen Exit-Status ungleich Null zurückgibt), wenn die Datei nicht vorhanden war, der erste jedoch aufgrund der Option -f(kurz für --force) erfolgreich ist. Dies kann je nach Situation ein wichtiges Detail sein.

Wenn Sie jedoch an die Datei anhängen, liegt dies eher daran, dass Ihr Skript verwendet >>, um etwas in die Datei umzuleiten. Ersetzen Sie einfach >>mit >. Es ist schwer zu sagen, da Sie keinen Code angegeben haben.

Beachten Sie, dass Sie so etwas test -f /p/a/t/h && rm /p/a/t/htun können, dies jedoch völlig sinnlos ist. Es ist durchaus möglich, dass der Test true zurückgibt, aber das / p / a / t / h nicht vorhanden ist, bevor Sie versuchen, es zu entfernen, oder schlimmer noch, der Test schlägt fehl und das / p / a / t / h wird erstellt bevor Sie den nächsten Befehl ausführen, der erwartet, dass er nicht existiert. Dies zu versuchen ist eine klassische Rennbedingung. Tu es nicht.

William Pursell
quelle
5
Dies ist nicht hilfreich, wenn sie wissen müssen, ob es existiert und gelöscht wurde. Stderr zu essen bietet das nicht. Wenn Sie die Existenz nicht behandeln, können Sie kein umfassenderes Skript ausführen, ohne dass dies fehlschlägt.
Uchuugaka
@uchuugaka Dies ist eine einfache Lösung, wenn es Ihnen egal ist, ob eine Datei vorhanden ist. Sie möchten lediglich sicherstellen, dass sie nicht vorhanden ist.
Lukas Liesis
Gute Antworten sollten in Kürze und vollständig über die Nebenwirkungen sein, ist die Verallgemeinerung meiner Nachricht, aber Shell-Skripte möchten häufig wissen, was gefunden wird oder nicht und was gehandelt wird oder nicht.
Uchuugaka
rm /p/a/t/h 2> /dev/nullDer Rückkehrcode ( echo $?) wird nicht als 0 beibehalten, wenn die Datei nicht vorhanden ist. Das würde dazu führen, dass Jenkins Jobs fehlschlagen, nur weil wir versucht haben, eine nicht vorhandene Datei zu löschen.
ViFI
@uchuugaka - Ich habe es seit einiger Zeit vermieden, auf diesen Kommentar zu antworten, aber er muss angesprochen werden. Es ist immer eine schlechte Idee, zu überprüfen, ob die Datei vorhanden ist, bevor Sie sie löschen . Siehe den letzten Absatz meiner Antwort. Es gibt eine inhärente Rassenbedingung, die mit solchen Dingen einfach nicht vermieden werden kann. Wenn Sie eine vorhandene Datei nicht überschreiben möchten, können Sie eine Shell-spezifische Magie ausprobieren (wie noclobberin Bash) oder die vorhandene Datei so ändern, dass die Umleitung fehlschlägt, wenn die Datei vorhanden ist (die Race-Bedingung wird nicht vermieden). Aber alles, was Sie tun können, ist, die Fehler subtiler zu machen.
William Pursell
126

Ein anderer einzeiliger Befehl, den ich verwendet habe, ist:

[ -e file ] && rm file
liwp_Stephen
quelle
11
Oder alternativ: [ ! -e Datei] || rm Datei. Diese Version gibt 0 anstelle eines Fehlers zurück.
Nawfel Bgh
@nawfelbgh Danke, das ist großartig, um ein längeres Skript zu verketten.
Abe
83

Sie können dies verwenden:

#!/bin/bash

file="file_you_want_to_delete"

if [ -f $file ] ; then
    rm $file
fi
Jindra Helcl
quelle
4
Dies sollte die ausgewählte Antwort sein.
Internet
Einfach und leicht zu lesen und stellt außerdem sicher, dass echo $?keine 1 angezeigt wird, wenn keine Datei vorhanden ist.
ViFI
Bei Bedarf können Sie dies auch als Einzeiler tun, siehe meine Antwort unten.
Nbeuchat
65

Wenn Sie den Schritt ignorieren möchten, um zu überprüfen, ob eine Datei vorhanden ist oder nicht, können Sie einen recht einfachen Befehl verwenden, der die Datei löscht, falls vorhanden, und keinen Fehler auslöst, wenn sie nicht vorhanden ist.

 rm -f xyz.csv
greperror
quelle
1
Dies ist nur ein Duplikat eines Teils der höchsten bewerteten Antwort, ab dem Jahr 2015
forgivenson
15
Die Hauptantwort erklärte nicht, dass mit dem -fes keinen Fehler werfen würde. Diese Antwort hat mir geholfen, danke.
Doug
Stimmen Sie Doug zu, obwohl dies ein guter Anwendungsfall für eine Wiki-ähnliche Bearbeitung einer Antwort zu sein scheint.
Philip
16

Ein Einzeiler-Shell-Skript zum Entfernen einer Datei, falls diese bereits vorhanden ist (basierend auf der Antwort von Jindra Helcl):

[ -f file ] && rm file

oder mit einer Variablen:

#!/bin/bash

file="/path/to/file.ext"
[ -f $file ] && rm $file
nbeuchat
quelle
13

So etwas würde funktionieren

#!/bin/sh

if [ -fe FILE ]
then 
    rm FILE
fi 

-f prüft, ob es sich um eine reguläre Datei handelt

-e prüft, ob die Datei existiert

Einführung in if für weitere Informationen

BEARBEITEN: -e, das mit -f verwendet wird, ist redundant, wenn -f allein verwendet werden sollte

P1kachu
quelle
-aist veraltet, verwenden Sie -estattdessen.
Mziccard
mein schlechtes, behoben. Danke @mziccard
P1kachu
Dies führt zu Fehlern in Verzeichnissen oder Links oder anderen nicht normalen Dateien. Es ist imho besser / sicherer zu bedienen -f.
Jindra Helcl
1
OK. nach wie vor, die -ein -feist überflüssig, da -fauch überprüft die Existenz der Datei soweit ich weiß ..
Jindra Helcl
Wenn ich bearbeite, mache ich nur ein Duplikat aus Ihrer Antwort, aber ich werde es präzisieren
P1kachu
4

if [ $( ls <file> ) ]; then rm <file>; fi

Wenn Sie Ihre Ausgabe >stattdessen mit umleiten >>, wird die vorherige Datei überschrieben

nLee
quelle
3
Dies ist kein Einzeiler, sorry, aber das @liwp_Stephen ist das.
fiorentinoing
Selbst wenn es richtig zitiert wird, bricht dies, wenn filees so etwas ist5 -lt 2
William Pursell