GNU/Linux >> LINUX-Kenntnisse >  >> Linux

Fehler Argumentliste zu lang für rm-, cp-, mv-Befehle

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

Linux
  1. Spickzettel für allgemeine Linux-Befehle

  2. 10 Linux-Befehle für die Netzwerkdiagnose

  3. Grep für mehrere Zeichenfolgen in Dateien und dann die Dateien in der Reihenfolge ihrer Größe auflisten?

  4. Kann -lm nicht finden?

  5. Linux-Suchbefehle

FreeDOS-Befehle für Linux-Fans

Wie kann die Tiefe für die rekursive Dateiliste begrenzt werden?

SFTP-Fehler Empfangene Nachricht zu lang

pkg-config-Fehler kann nicht gefunden werden

Intermittierender OSError:[Errno 7] Argumentliste zu lang mit kurzem Befehl (~125 Zeichen)

Wie kann ich alle Dateien aus einem Verzeichnis löschen, wenn die Argumentliste zu lang gemeldet wird?