Eine andere Antwort ist, xargs
zu erzwingen um die Befehle stapelweise abzuarbeiten. Zum Beispiel an delete
die Dateien 100
jeweils cd
in das Verzeichnis und führen Sie Folgendes aus:
echo *.pdf | xargs -n 100 rm
tl;dr
Es ist eine Kernel-Beschränkung für die Größe des Befehlszeilenarguments. Verwenden Sie einen for
Schleife statt.
Ursprung des Problems
Dies ist ein Systemproblem im Zusammenhang mit execve
und ARG_MAX
Konstante. Dazu gibt es reichlich Dokumentation (siehe man execve, debian's wiki, ARG_MAX details).
Grundsätzlich erzeugt die Erweiterung einen Befehl (mit seinen Parametern), der ARG_MAX
überschreitet limit.On Kernel 2.6.23
, wurde das Limit auf 128 kB
gesetzt . Diese Konstante wurde erhöht und Sie können ihren Wert erhalten, indem Sie Folgendes ausführen:
getconf ARG_MAX
# 2097152 # on 3.5.0-40-generic
Lösung:Verwenden von for
Schleife
Verwenden Sie einen for
Schleife, wie es auf BashFAQ/095 empfohlen wird, und es gibt keine Begrenzung außer für RAM/Speicherplatz:
Testlauf, um sicherzustellen, dass das gelöscht wird, was Sie erwarten:
for f in *.pdf; do echo rm "$f"; done
Und führen Sie es aus:
for f in *.pdf; do rm "$f"; done
Auch dies ist ein portabler Ansatz, da glob ein starkes und konsistentes Verhalten zwischen Shells hat (Teil der POSIX-Spezifikation).
Hinweis: Wie in mehreren Kommentaren angemerkt, ist dies in der Tat langsamer, aber wartungsfreundlicher, da es komplexere Szenarien anpassen kann, z. B. wo man mehr als nur eine Aktion machen will.
Lösung:Verwenden von find
Wenn Sie darauf bestehen, können Sie find
verwenden aber wirklich benutze keine xargs da es "gefährlich (kaputt, ausnutzbar usw.) ist, wenn Eingaben gelesen werden, die nicht durch NUL getrennt sind" :
find . -maxdepth 1 -name '*.pdf' -delete
Mit -maxdepth 1 ... -delete
statt -exec rm {} +
erlaubt find
um die erforderlichen Systemaufrufe einfach selbst auszuführen, ohne einen externen Prozess zu verwenden, daher schneller (dank @chepner-Kommentar).
Referenzen
- Ich erhalte "Argument list too long". Wie kann ich eine große Liste in Blöcken verarbeiten? @ wollrand
- execve(2) - Linux-Manpage (Suche nach ARG_MAX);
- Fehler:Argumentliste zu lang @ Debians Wiki;
- Warum erhalte ich „/bin/sh:Argument list too long“, wenn ich Argumente in Anführungszeichen übergebe? @ SuperUser
find
hat einen -delete
Aktion:
find . -maxdepth 1 -name '*.pdf' -delete
Der Grund dafür ist, dass Bash das Sternchen tatsächlich auf jede passende Datei erweitert, wodurch eine sehr lange Befehlszeile entsteht.
Versuchen Sie Folgendes:
find . -name "*.pdf" -print0 | xargs -0 rm
Warnung: dies ist eine rekursive Suche und findet (und löscht) auch Dateien in Unterverzeichnissen. -f
anheften auf den Befehl rm nur, wenn Sie sicher sind, dass Sie keine Bestätigung wünschen.
Sie können Folgendes tun, um den Befehl nicht rekursiv zu machen:
find . -maxdepth 1 -name "*.pdf" -print0 | xargs -0 rm
Eine weitere Option ist die Verwendung von -delete
von find Flagge:
find . -name "*.pdf" -delete