Wie kann ich rm keine Fehlermeldung geben, wenn eine Datei nicht vorhanden ist?

216798
Jason Baker

Ich schreibe ein Makefile, das am Ende der Kompilierung einige unbrauchbare Dateien bereinigt. Wenn ein Ziel bereits erstellt wurde, wird dieses Ziel natürlich übersprungen, und die unbrauchbare Datei ist möglicherweise nicht vorhanden. Also wenn ich das mache:

rm lexer.ml interpparse.ml interpparse.mli 

Ich kann Fehlermeldungen erhalten, weil eine der Dateien nicht vorhanden ist. Gibt es eine Möglichkeit rm, diese Dateien zu 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 klingt nach fast dem, was ich will, aber ich bin mir nicht wirklich sicher, was die Berechtigungen betrifft. Gibt es eine Möglichkeit, dies zu tun?

277
Haben Sie einige `rm` in einer Sandbox ausprobiert? Es sieht so aus, als würde "-f" genau das tun, was Sie wollen, unabhängig vom Globbing. JMD vor 14 Jahren 0
Wenn die Berechtigungen dies nicht zulassen, versucht rm mit der Option `-f` immer noch, es zu löschen. Es wird scheitern Es wird Ihnen nicht sagen, dass es fehlgeschlagen ist. Nützlich, wenn der Dateiname eine Variable oder eine Kugel ist. LawrenceC vor 11 Jahren 0

12 Antworten auf die Frage

234
Dave Webb

Die -fOption ist definitiv das, was Sie verwenden möchten.

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

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

So rmwerden Sie gewarnt, wenn Sie versuchen, eine Datei zu löschen, für die Sie keine Schreibberechtigung haben. Dies ist zulässig, wenn Sie über Schreibberechtigungen für das Verzeichnis verfügen, jedoch etwas seltsam ist. Deshalb werden Sie rmnormalerweise darauf aufmerksam gemacht.

Die meisten, aber nicht alle Systeme werden fragen (denke ich). Einige erfordern "-i". DaveParillo vor 14 Jahren 1
Wenn Sie die Fehlermeldung, aber nicht den Fehler-Exit-Code erhalten möchten, lesen Sie die Antwort von [Giel Berkers] (http://superuser.com/a/887349/64750). Ich verwende `set -e` in all meinen Bash-Skripten, so dass das Skript beendet wird, nachdem ein Befehl einen Fehler ausgegeben hat. Ich möchte oft, dass mir ein Skript sagt, ob `rm` einen Fehler ausgegeben hat, aber trotzdem trotzdem fortfahren. geht weiter. cledoux vor 7 Jahren 1
87
Giel Berkers

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

Fügen Sie einfach eine ODER-Anweisung nach Ihrem Befehl ein:

rm -rf my/dir || true 

Wenn Anweisung # 1 fehlschlägt (wirft einen Fehler), führen Sie Anweisung # 2 aus. Dies ist einfach true.

Es druckt den Fehler und setzt die Ausführung fort, die für meinen Fall gewünscht wurde. worldsayshi vor 8 Jahren 1
Oder einfach `rm -rf mein / dir ||:` um noch prägnanter zu sein (`:` steht für `true`) Godsmith vor 7 Jahren 4
Die bessere Lösung meiner Meinung nach. Es ist leicht sichtbar, was passiert und warum der Ergebniscode ignoriert wird. Ich mag das! Mavamaarten vor 6 Jahren 0
72
Robert Li

Ich bin zu spät zur Party, aber ich benutze das die ganze Zeit. Fügen Sie in einem Makefile -den Anfang einer Zeile hinzu, um den Rückgabewert dieser Zeile zu ignorieren. So wie:

-rm lexer.ml interpparse.ml interpparse.mli
Dadurch werden jedoch immer noch Fehler an die Konsole ausgegeben, was Sie dazu bringt, 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 vor 7 Jahren 9
@ Godsmith Ich würde lieber einen Fehler ignorieren, als rekursives Löschen zu erzwingen. Das könnte sehr ungezogen sein. Und +1 für die Makefile-spezifische Syntax Daishi vor 6 Jahren 0
Wenn rm -rf "unartig" sein kann, bedeutet dies, dass Sie make außerhalb eines Verzeichnisses unter Versionskontrolle verwenden. Warum? Godsmith vor 6 Jahren 0
Bitte geben Sie einen Link zur Dokumentation an. Konnte eine Beschreibung dieser Funktion finden. George Sovetov vor 6 Jahren 0
@GeorgeSovetov https://www.gnu.org/software/make/manual/make.html#Errors Robert Li vor 6 Jahren 0
Ich denke das ist überlegen. '-f` überspringt auch den interaktiven Modus, überspringt schreibgeschützte Dateien usw. - diese Lösung erfüllt jedoch genau das, was OP verlangt. Blauhirn vor 6 Jahren 0
9
user135299

If you don't want to use the -f option, an alternative is:

rm filethatdoesntexist 2> /dev/null 

This will just keep errors from being printed.

Leider wird immer noch ein Fehlercode ausgegeben. Shaun McDonald vor 10 Jahren 5
7
Nick Bastin

Wenn Sie eine Möglichkeit finden, die Dateinamen zu globieren, können Sie rmsich nicht beschweren, wenn keine Übereinstimmung gefunden wird. So etwas wie lexer.m* interpparse.*usw. sollte für Sie funktionieren (seien Sie vorsichtig, dass Sie nicht zu viel löschen). Dies -fist auch eine absolut vernünftige Vorgehensweise, solange Sie nicht hoffen, dass Dateiberechtigungen Sie vor dem Löschen einer Datei schützen, die Sie nicht wollten. Wenn Sie sie nicht löschen möchten, setzen Sie sie nicht ein In der Liste.

Das Globbing wäre nicht in Frage, da es eine lexer.mll-Datei gibt, die ich nicht löschen möchte. Danke, dass Sie gezeigt haben, warum -f angemessen ist. Ich denke, ich neige dazu, nach einem zu vielen fehlgeleiteten "sudo rm -rf" zu vorsichtig zu sein. Jason Baker vor 14 Jahren 0
Nicht einmal ein restriktiveres `lexer.m?` ...? Das würde "lexer.ml" und "lexer.mz" fangen, aber nicht "lexer.mll" oder "lexer.mla". JMD vor 14 Jahren 0
@JMD: Ich denke, es hängt von deiner Shell ab und welche Pattern-Matching-Unterstützung sie für das Globbing bietet. Nick Bastin vor 14 Jahren 1
5
mouviciel

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

Wenn Sie nicht über die erforderlichen Berechtigungen zum Entfernen einer Datei verfügen, wird diese nicht entfernt.

ABER wenn Sie über ausreichende Berechtigungen zum Ändern von Berechtigungen verfügen, wird Ihre Datei entfernt. Dies ist der Fall, wenn Sie der Besitzer einer Datei mit Leseberechtigungen für Besitzer sind (-r --------). Als Besitzer können Sie es chmod u+wdann entfernen: rm -fDiese Datei wird entfernt.

3
Bogdan

Vielleicht könnte eine Zeile ähnlich helfen mit:

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

Ich weiß, dass dies nicht sehr klug ist, aber es macht den Job.

2
reinierpost

Eine Alternative:

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

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

Haben Sie versucht, \ (Backslash) am Ende einer Zeile zu verwenden, damit es beim nächsten fortgesetzt werden kann? some vor 11 Jahren 0
@some: Ja, sie können sich auf mehrere Zeilen verteilen, aber um sie über Rezepte zu teilen, muss die Definition in eine Make-Variable eingefügt werden. reinierpost vor 11 Jahren 0
2
teh_senaus

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

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

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