Frage Wie mache ich rm keinen Fehler, wenn eine Datei nicht existiert?


Ich schreibe ein Makefile, das am Ende der Kompilation einige nutzlose Dateien aufräumen wird. Wenn ein Ziel bereits erstellt wurde, überspringt es dieses Ziel natürlich und die nutzlose Datei ist möglicherweise nicht da. Also wenn ich das tue:

rm lexer.ml interpparse.ml interpparse.mli

Ich bekomme möglicherweise Fehler, weil eine der Dateien nicht existiert. Gibt es eine Möglichkeit zu sagen? rm diese Dateien ignorieren?

Beim Lesen der Manpage sehe ich folgende Option:

 -f          Attempt to remove the files without prompting for confirma-
             tion, regardless of the file's permissions.  If the file does
             not exist, do not display a diagnostic message or modify the
             exit status to reflect an error.  The -f option overrides any
             previous -i options.

Das hört sich an, wie fast was ich will, aber ich bin nicht wirklich sicher über die Berechtigungen Teil. Gibt es eine Möglichkeit, dies zu tun?


261
2017-11-27 16:43


Ursprung


Hast du es versucht? rm in einer Sandbox? Es sieht aus wie -f macht genau das, was Sie wollen, unabhängig vom Globbing. - JMD
Wenn die Erlaubnis es nicht erlaubt, wird rm mit der -f Option versuchen Sie immer noch, es zu löschen. Es wird scheitern. Es wird dir nicht sagen, dass es fehlgeschlagen ist. Nützlich, wenn der Dateiname eine Variable oder ein Glob ist. - LawrenceC


Antworten:


Das -f Option ist definitiv, was Sie verwenden möchten.

Die Bestätigung über Dateiberechtigungen, auf die es sich bezieht, lautet wie folgt:

$ touch myfile    
$ chmod 400 myfile
$ rm myfile       
rm: remove write-protected regular empty file `myfile'?

Damit rm wird Sie warnen, wenn Sie versuchen, eine Datei zu löschen, für die Sie keine Schreibberechtigung haben. Dies ist erlaubt, wenn Sie Schreibrechte für das Verzeichnis haben, aber etwas seltsam ist, weshalb rm warnt dich normalerweise davor.


221
2017-11-27 16:54



Die meisten, aber nicht alle Systeme werden fragen (denke ich). Einige erfordern -i. - DaveParillo
Wenn Sie die Fehlermeldung, aber nicht den Fehler beenden möchten, finden Sie in der Antwort von Giel Berkers. ich benutze set -e in all meinen Bash-Skripten, so dass das Skript beendet wird, nachdem ein Befehl einen Fehler verursacht hat. Ich möchte oft ein Skript, um mir zu sagen, ob rm gab einen Fehler, aber trotzdem weiter. geht weiter. - cledoux


Eine andere Lösung ist diese: https://stackoverflow.com/questions/11231937/bash-ignoring-error-for-a-particular-command

Fügen Sie einfach eine OR-Anweisung nach Ihrem Befehl hinzu:

rm -rf my/dir || true

Auf diese Weise, wenn die Anweisung # 1 fehlschlägt (Fehler löst), führen Sie die Anweisung # 2 aus, was einfach ist true.


77
2018-03-09 12:39



Es druckt den Fehler und setzt die Ausführung fort, die für meinen Fall gewünscht wurde. - worldsayshi
Oder nur rm -rf my/dir ||: um noch prägnanter zu sein (: Kurzform für true) - Godsmith
Die bessere Lösung meiner Meinung nach. Es ist leicht ersichtlich, was passiert und warum der Ergebniscode ignoriert wird. Ich mag das! - Mavamaarten


Ich bin viel zu spät zur Party, aber ich benutze es die ganze Zeit. In einem Makefile hinzufügen - an den Anfang einer Zeile, um den Rückgabewert dieser Zeile zu ignorieren. Wie so:

-rm lexer.ml interpparse.ml interpparse.mli

69
2017-12-23 23:12



Dadurch wird trotzdem ein Fehler auf der Konsole ausgegeben, der Sie daran erinnert, Fehler in der make-Ausgabe zu ignorieren, was wahrscheinlich nicht das ist, was Sie wollen. RM-RF ist meiner Meinung nach eine bessere Option. - Godsmith
@Godsmith Ich würde lieber einen Fehler ignorieren als rekursives Löschen. Das könnte sehr ungezogen sein. Und +1 für die Makefile-spezifische Syntax - Daishi
Wenn rm -rf "ungezogen" sein könnte, bedeutet dies, dass Sie make außerhalb eines Verzeichnisses mit Versionskontrolle verwenden. Warum? - Godsmith
Bitte geben Sie einen Link zur Dokumentation an. Kann eine Beschreibung dieser Funktion finden. - George Sovetov
@GeorgeSovetov gnu.org/software/make/manual/make.html#Errors - Robert Li


Wenn Sie die Option -f nicht verwenden möchten, ist eine Alternative:

rm filethatdoesntexist 2> /dev/null 

Dies wird nur verhindern, dass Fehler gedruckt werden.


8
2018-06-12 19:46



Leider gibt dies immer noch einen Fehlercode. - Shaun McDonald


Wenn Sie einen Weg finden glob die Dateinamen, rm Ich werde mich nicht beschweren, wenn es keine Übereinstimmung findet. So etwas wie lexer.m* interpparse.*usw. sollte für Sie arbeiten (seien Sie vorsichtig, dass Sie nicht zu viel löschen, natürlich). Ebenfalls, -f Dies ist ein absolut vernünftiger Weg, solange Sie nicht hoffen, dass die Dateiberechtigungen Ihnen das Löschen einer Datei ersparen, die Sie nicht möchten - wenn Sie sie nicht löschen wollen, legen Sie sie nicht in die Liste.


7
2017-11-27 16:48



Das Globbing würde nicht in Frage kommen, da es eine Datei lexer.mll gibt, die ich nicht löschen möchte. Danke, dass du gezeigt hast, warum -f sinnvoll ist. Ich nehme an, ich tendiere dazu, vorsichtig zu sein, nachdem zu viele fehlgeleitet wurden sudo rm -rf . - Jason Baker
Nicht einmal restriktiver lexer.m? ...? Das würde fangen lexer.ml und lexer.mz, aber nicht lexer.mll oder lexer.mla. - JMD
@JMD: Ich nehme an, es hängt von deiner Shell ab und welcher Muster-Matching-Unterstützung es für Globbing bietet. - Nick Bastin


Die Option -f bedeutet, dass Sie nicht gefragt werden, wenn etwas nicht wie erwartet ist. Es bedeutet nicht, dass Berechtigungen nicht berücksichtigt werden.

Wenn Sie nicht über ausreichende Berechtigungen verfügen, um eine Datei zu entfernen, wird sie nicht entfernt.

ABERWenn Sie über ausreichende Berechtigungen zum Ändern von Berechtigungen verfügen, wird die Datei entfernt. Dies ist der Fall, wenn Sie der Eigentümer einer Datei mit schreibgeschützten Berechtigungen für den Eigentümer (-r --------) sind. Als Besitzer können Sie chmod u+w, dann entferne es: rm -f wird diese Datei entfernen.


5
2017-11-27 19:27





Vielleicht könnte eine Zeile ähnlich helfen mit:

touch fakefile.exe fakefile.o && rm *.o *.exe

Ich weiß, dass das nicht sehr schlau ist, aber es macht den Job.


3
2018-03-11 10:36





Eine Alternative:

RmIfIsFile() {  for f in "$@"; do [ -f $f ] && rm $f; done; };  RmIfIsFile lexer.ml interpparse.ml interpparse.mli

Schade, dass Makefiles Shell-Funktionsdefinitionen nicht über mehrere Zeilen hinweg teilen können.


2
2017-11-27 17:44



Haben Sie versucht, \ (Backslash) am Ende einer Zeile zu verwenden, damit es beim nächsten fortfahren kann? - some
@some: Ja, sie können auf mehrere Zeilen verteilt werden, aber um sie über Rezepte hinweg zu teilen, müssen Sie die Definition in eine make-Variable einfügen. - reinierpost


Hier ist, was ich in Shell-Skripten verwende. Es verbirgt die Fehlermeldung und den Fehlercode.

rm doesnotexist 2> /dev/null || echo > /dev/null

2
2018-06-11 13:55





Sie können die Dateien berühren, bevor Sie sie löschen. das würde sie schaffen, wenn sie nicht existieren :-)

touch lexer.ml interpparse.ml interpparse.mli
rm lexer.ml interpparse.ml interpparse.mli

0
2018-02-02 16:11