Der Befehl bricht mit 'Argument list too long' ab, weil ein * zu viele Dateien liefert. So löst du es mit find und xargs statt Globbing.
Aufwand:
ca. 5 Min.
Voraussetzung:
Terminal
Das Symptom
Ein simpler Befehl – rm *.log, mv * /ziel/, grep muster * – und statt Arbeit
gibt es nur: bash: /bin/rm: Argument list too long. Der Befehl stimmt, die
Dateien existieren, und trotzdem läuft nichts. Als hätte die Shell schlicht die
Nerven verloren.
Die „Layer 8“-Wahrheit
Hat sie sozusagen. Der Fehler kommt gar nicht von rm oder grep, sondern vom
Kernel – und er tritt auf, bevor das Programm überhaupt startet. Denn * ist
keine Magie des Befehls, sondern wird von der Shell vorher zur kompletten Liste
aller passenden Dateinamen expandiert. Bei ein paar Dutzend Dateien ist das egal.
Bei Zehntausenden sprengt diese Liste zusammen mit der Umgebung das Systemlimit
ARG_MAX, und der Kernel lehnt den Aufruf rundheraus ab. Die Lösung ist nicht,
das Limit hochzuschrauben, sondern die Liste erst gar nicht als ein Monster-
Argument zu bauen. Genau dafür gibt es find und xargs: find reicht die
Dateien selbst weiter, xargs zerlegt sie in mehrere Aufrufe, die jeder brav
unter dem Limit bleiben. Dasselbe Ergebnis, nur eben in verdaulichen Häppchen
statt in einem Bissen, an dem sich der Kernel verschluckt.
Die echte, verifizierte Lösung
1000 % faktenbasiert. Jeder Befehl ist real, jeder Pfad existiert. Schritt für Schritt:
1.
Die Ursache verstehen
Nicht das Programm ist überfordert, sondern die Kommandozeile zu lang. Das aktuelle Limit lässt sich anzeigen:
getconf ARG_MAX
2.
Mit find und -exec lösen
find übergibt die Treffer selbst an den Befehl. Das '+' am Ende bündelt sie in möglichst wenige, aber gültige Aufrufe – ganz ohne Glob-Expansion durch die Shell:
find . -maxdepth 1 -name '*.log' -exec rm {} +
3.
Alternativ mit xargs
find und xargs kombinieren. Die Nullbyte-Trennung (-print0 / -0) macht es robust gegen Leerzeichen in Dateinamen, und xargs stückelt die Liste automatisch unter das Limit:
Dieselbe Technik funktioniert für mv, cp, chmod oder grep. Statt 'grep muster *' zum Beispiel find mit xargs verwenden, damit die Argumentliste nie zu groß wird:
Der Fehler kommt nicht vom Programm selbst, sondern vom Kernel. Bevor rm, mv oder cp überhaupt starten, expandiert die Shell das '*' zur vollständigen Liste aller Dateinamen. Übersteigt diese Liste zusammen mit der Umgebung das Systemlimit ARG_MAX, verweigert der Kernel das Ausführen des Befehls – noch bevor das Programm eine einzige Datei sieht.
?Warum helfen find und xargs, wenn 'rm *' nicht funktioniert?
Weil sie die Liste gar nicht erst als ein einziges riesiges Argument aufbauen. find übergibt die Dateien intern, und xargs stückelt sie in mehrere Aufrufe, die jeder unter dem Limit bleiben. Statt eines übergroßen Kommandos entstehen viele handliche – das Ergebnis ist dasselbe, nur ohne Absturz.
?Betrifft das nur rm?
Nein. Jedes Programm, das über eine Glob-Expansion sehr viele Argumente bekommt, kann darüberstolpern – mv, cp, chmod, grep, ls und andere gleichermaßen. Es ist ein Limit der Kommandozeile, kein Bug eines einzelnen Befehls. Das aktuelle Limit zeigt 'getconf ARG_MAX'.
Belege
Diese Seite ist gegen die folgenden Primärquellen geprüft – Hersteller, Standard oder Gesetzestext. Wer es nicht glaubt, muss es nicht: Da steht, wo es nachzulesen ist.