Hast rm nicht gemeldet, wenn eine Datei fehlt?

37

Ich habe ein Bash-Skript, mit dem ich Dateien aus verschiedenen Verzeichnissen entfernen möchte. Oft werden sie nicht da sein, weil sie nicht generiert wurden und das ist in Ordnung. Gibt es eine Möglichkeit, das Skript dazu zu bringen, diesen Fehler nicht zu melden, aber wenn rm eine andere Ausgabe hat, um dies zu melden?

Alternativ gibt es einen besseren Befehl zum Entfernen der Datei, die weniger verrauscht sein wird?

Flackerfliege
quelle

Antworten:

64

Verwenden Sie die -fOption. Nicht vorhandene Dateien werden unbemerkt ignoriert.

Von man rm:

   -f, --force
          ignore nonexistent files and arguments, never prompt

[Der Teil "Nie auffordern" bedeutet, dass (a) -falle zuvor angegebenen -ioder ausgewählten -IOptionen überschrieben werden und (b) schreibgeschützte Dateien ohne Rückfrage gelöscht werden.]

Beispiel

Ohne -f, rmwerde über fehlende Dateien klagen:

$ rm nonesuch
rm: cannot remove ‘nonesuch’: No such file or directory

Mit -fwird es still sein:

$ rm -f nonesuch
$
John1024
quelle
4
Oh, ich neu, der nicht zur Entfernung aufgefordert hat, hat nicht bemerkt, dass es auch nicht existierende ignoriert hat. Ich habe das total übersprungen, als ich einen Mann angesehen habe. :-) Vielen Dank. Ich werde dies als Antwort markieren, sobald es mir gestattet ist.
Flickerfly
9

Wenn Ihre Anforderung ist , dass rmnicht über fehlende Dateien nicht beschweren, aber dass Sie auch alle wollen andere Ausgabe von rm, mein Vorschlag zum ersten Test für die Zieldatei Existenz wäre, und rufen Sie nur rm( ohne die -fFlagge) , wenn die Datei tatsächlich vorhanden ist.

# rest of script
# ...
[ -e "$file" ] && rm "$file"
# ...
# rest of script

Wenn Sie rm -feine Datei aufrufen, die beispielsweise keine Schreibrechte für Benutzer hat, wird die Datei entfernt und die normale Eingabeaufforderung für dieses Szenario nicht ausgegeben.

Für den Fall, dass Sie dieselbe Idee mit mehreren Dateien verwenden möchten, würde ich eine Funktionsdefinition erstellen, wie zum Beispiel:

qrm() {
  for f
  do
    [ -e "$f" ] && rm "$f"
  done
}

Verwenden Sie es wie folgt: qrm file1 file2-does-not-exist *.txt etc here

Jeff Schaller
quelle
1
Es ist erwähnenswert, dass die Wahrscheinlichkeit sehr gering ist, dass die Datei zwischen dem Test und dem Entfernen gelöscht (oder erstellt) wird, aber ich kann mir nicht vorstellen, dass dies in einer typischen Situation relevant ist, in der ein Shell-Skript verwendet wird .
David Z
7

Sie haben angegeben, dass Sie rmbeim Ausführen des Befehls immer noch andere Ausgaben sehen möchten, diese werden jedoch durch die Verwendung der -fOption unterdrückt. Sie müssen STDERR nach Ihren Wünschen filtern, was etwas schwierig ist, vorausgesetzt, Sie möchten, dass alles andere angezeigt wird.

Sie möchten einen Befehl wie diesen verwenden:

rm -f filename 3>&1 1>&2 2>&3 3>&- | grep -v 'No such file or directory'

Befehl erklärt:

  • -f Das Argument ist, es durchzusetzen und nicht zur Bestätigung oder zu Fehlern aufzufordern
  • 3>&1 1>&2 2>&3 3>&-ist es, STDOUT und STDERR für die Filterung umzuschalten (dazu können Sie hier mehr lesen , wenn Sie möchten
  • | grep -v 'No such file or directory' filtert die Nachricht heraus, die Sie nicht sehen möchten

Wenn Sie Fehlermeldungen nur vollständig unterdrücken möchten, können Sie den folgenden Befehl ausführen:

rm filename 2> /dev/null

Dieser Befehl leitet STDERR nach / dev / null um, sodass er beim Ausführen des Befehls nicht angezeigt wird.

BriGuy
quelle
1
(AFAICS) rmohne -vnie Ausgaben zu stdout, nur stderr, also in diesem Fall könnten Sie nur 2>&1 | grepohne den Tanz, der allgemeiner nützlich ist,
dave_thompson_085
4

Alternativ können Sie den findBefehl mit der -deleteOption verwenden. Dies löscht (offensichtlich) nur die Dateien, die es findet, so dass es niemals warnt, wenn keine vorhanden sind. Ein Beispiel könnte sein:

find /var/log/triffids/ -name "*.log" -mtime 30 -delete

Diese durchsucht das /var/log/triffids/Verzeichnis und löscht alle Dateien mit dem .logSuffix, die seit mehr als 30 Tagen nicht mehr geändert wurden.

Es ist immer eine gute Idee, diese Befehle zuerst ohne die -deleteOption auszuführen , um sicherzustellen, dass die erwarteten Dateien gefunden werden.

seumasmac
quelle
Ich mag diese Option und werde eine Änderung in Betracht ziehen. Danke, dass du es geteilt hast.
Flickerfly
3

Aktivieren Sie die Option --force( -f) für rm:

-f, --force

Ignorieren Sie nicht vorhandene Dateien und Argumente

heemayl
quelle
2

Dies ist ein Hack, aber Sie könnten immer touchdie Datei entfernt werden. Wenn es nicht vorhanden ist, wird es erstellt und rmkann entfernt werden.

Mega
quelle
Ich mag das, abgesehen von der Leistung - wie teuer ist es, mehrere K Dateien zu berühren, anstatt nur diejenigen zu löschen, die nicht existieren?
Dani_l
0

Sie können -fnach Belieben die folgenden Befehle verwenden:

Versuchen Sie, die Dateien zu entfernen, ohne zur Bestätigung aufzufordern, unabhängig von den Berechtigungen der Datei. Wenn die Datei nicht vorhanden ist, zeigen Sie keine Diagnosemeldung an und ändern Sie den Beendigungsstatus nicht, um einen Fehler anzuzeigen. Denken Sie auch daran, dass die Option -f alle vorherigen Optionen -i überschreibt.

rm -f xyz-directory

wird Sie nicht dazu auffordern, und genau das tun, was Sie wollen.

Ankit Jain
quelle
-1

Es gibt zwei Hauptmöglichkeiten: Wenn Sie die Option -f hinzufügen, wird der Fehler "nicht vorhanden" nicht angezeigt, und zwei: (funktioniert für fast alle Befehle), anstatt nur "thecommand" do "thecommand 2> / dev auszuführen / null "wobei" thecommand "der Befehl ist, den Sie ausführen.

John
quelle
1
Ich bin der Leitung aus dem Weg gegangen, weil ich keine anderen Fehler verlieren möchte, die auftreten könnten. Ich weiß nicht, was sie sein würden.
Flickerfly