Wenn Verzeichnisse sehr viele Dateien enthalten, kann es vorkommen, dass über die Bash abgesetzte Befehle auf diese Dateien mit der Fehlermeldung “Argumentenliste zu lang” ihren Dienst versagen.
Das liegt daran, dass als Parameter übergebene Platzhalter (z.B. das “*”) vor der eigentlichen Befehlsausführung in die vollständigen Namen der Dateien konvertiert und dann an den auszuführenden Befehl übergeben werden.
So wird, wenn das Verzeichnis /tmp die Dateien “Datei1″, “Datei2″ und “Datei3″ enthält, aus:
$ rm /tmp/*
vor der eigentlichen Befehlsauführung der Befehl:
$ rm /tmp/Datei1 /tmp/Datei2 /tmp/Datei3
generiert und ausgeführt.
Sind zu viele Dateien in /tmp beschwert sich “rm” dann darüber, dass es so viele Dateinamen nicht auf einmal abarbeiten kann.
Eine Möglichkeit wäre jetzt, den “rm”-Befehl über geschickt gewählte Dateimuster immer nur mit Häppchen zu füttern, die der Befehl noch abarbeiten kann, die Arbeit artet dann aber schnell in einen Tippmarathon aus.
Einfacher (und eleganter) ist es, “find” und “xargs” als Unterstützung einzubinden:
$ find /tmp -maxdepth 1 -name "*" -print0 |xargs -0 rm -f
Auf diese Weise gibt “find” die Dateinamen der zu löschenden Dateien zurück und über xargs wird dann für jeden dieser Dateinamen ein eigener “rm”-Befehl abgesetzt.
22. Dezember 2006 um 14:50
Der zweite Befehl ist nicht komplett äquivalent zum ersten, der erste würde Dateien in Unterverzeichnissen nicht löschen, der zweite IMHO schon.
Und die Pipe ist unnötig, find kann das auch so:
find /tmp/ -maxdepth 1 -name ‘*’ -type f -exec rm ‘{}’ \;
entspräche rm /tmp/*
24. Dezember 2006 um 22:47
@Thinker: Danke für den Hinweis. Du hast natürlich recht, der maxdepth-Parameter fehlte, ich habe ihn oben ergänzt.