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.
Ü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.
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:
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 $my_file
, oder? Welche Shell benutzt du?Antworten:
Überprüfen Sie nicht, ob die Datei vorhanden ist, sondern entfernen Sie sie.
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/h
tun 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.quelle
rm /p/a/t/h 2> /dev/null
Der 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.noclobber
in 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.Ein anderer einzeiliger Befehl, den ich verwendet habe, ist:
quelle
Sie können dies verwenden:
quelle
echo $?
keine 1 angezeigt wird, wenn keine Datei vorhanden ist.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.
quelle
-f
es keinen Fehler werfen würde. Diese Antwort hat mir geholfen, danke.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:
quelle
So etwas würde funktionieren
-f prüft, ob es sich um eine reguläre Datei handelt
-e prüft, ob die Datei existiert
BEARBEITEN: -e, das mit -f verwendet wird, ist redundant, wenn -f allein verwendet werden sollte
quelle
-a
ist veraltet, verwenden Sie-e
stattdessen.-f
.-e
in-fe
ist überflüssig, da-f
auch überprüft die Existenz der Datei soweit ich weiß ..if [ $( ls <file> ) ]; then rm <file>; fi
Wenn Sie Ihre Ausgabe
>
stattdessen mit umleiten>>
, wird die vorherige Datei überschriebenquelle
file
es so etwas ist5 -lt 2