Beim Versuch, ls *.txt | wc -l
ein Verzeichnis zu öffnen, das viele Dateien enthält , wird die folgende Fehlermeldung angezeigt:
-bash: /bin/ls: Argument list too long
Ist der Schwellenwert für diese "Argumentliste" von der Distribution oder der Computerspezifikation abhängig? Normalerweise würde ich das Ergebnis eines so großen Ergebnisses an andere Befehle leiten ( wc -l
zum Beispiel), damit ich mich nicht um die Grenzen des Terminals kümmere.
ls
-Ausgabe , was eine schlechte Idee ist. Vermeiden Sie es also besser. Informationen zum Zählen finden Sie unter Wie wird die Anzahl der Dateien in einem Verzeichnis am besten gezählt? Lesen Sie für eine knifflige Umgehung, warum for loop den Fehler "argument too long" nicht auslöst. .Antworten:
Ihre zu lange Liste der Argumente für Fehlermeldungen stammt aus dem * von
ls *.txt
.Diese Begrenzung ist eine Sicherheit sowohl für Binärprogramme als auch für Ihren Kernel. Auf dieser Seite finden Sie weitere Informationen dazu sowie zur Verwendung und Berechnung.
Es gibt keine solche Begrenzung der Rohrgröße. Sie können also einfach diesen Befehl eingeben:
NB: Unter modernen Linux werden seltsame Zeichen in Dateinamen (wie Zeilenumbrüche) mit Werkzeugen wie
ls
oder maskiertfind
, aber immer noch von * angezeigt . Wenn Sie mit einem alten Unix arbeiten, benötigen Sie diesen BefehlNB2: Ich habe mich gefragt, wie man eine Datei mit einer neuen Zeile im Namen erstellen kann. Es ist nicht so schwer, wenn Sie den Trick kennen:
quelle
-maxdepth 1
wenn Sie nicht beabsichtigen, Dateien in Unterverzeichnissen zu zählen.-exec echo \;
.find
. Diefind
auf OS X und auf busybox-basierten Systemen, und ich würde mir vorstellen, dass jedes BSD-basierte System den Dateinamen mit einem Zeilenumbruch anzeigt, der mit der Zählung zu schaffen machen würde.wc -l
zählt Zeilenumbrüche. Wir möchten , dass es Zeilenumbrüche gibt.Dies hängt hauptsächlich von Ihrer Version des Linux-Kernels ab.
Sie sollten in der Lage sein, das Limit für Ihr System zu sehen, indem Sie ausführen
Dies gibt an, wie viele Bytes eine Befehlszeile maximal haben darf, nachdem sie von der Shell erweitert wurde.
Unter Linux <2.6.23 beträgt das Limit normalerweise 128 KB.
Unter Linux> = 2.6.25 beträgt das Limit entweder 128 KB oder 1/4 Ihrer Stapelgröße (siehe
ulimit -s
), je nachdem, welcher Wert größer ist.Weitere Informationen finden Sie auf der Manpage execve (2) .
Leider kann
ls *.txt
das Problem durch Piping nicht behoben werden, da das Limit im Betriebssystem und nicht in der Shell liegt.Die Shell erweitert das
*.txt
und versucht dann aufzurufenund Sie haben so viele passende Dateien,
*.txt
dass Sie das 128-KB-Limit überschreiten.Sie müssen so etwas tun
stattdessen.
(Siehe auch Shawn J. Goffs Kommentare zu Dateinamen, die Zeilenumbrüche enthalten.)
quelle
.
und was das-maxdepth 1
in der letzten Zeile bedeutet? Vielen Dank! : D.
bedeutet aktuelles Verzeichnis,-maxdepth 1
dh es sucht nicht in Unterverzeichnissen. Dies sollte mit den gleichen Dateien wie übereinstimmen*.txt
.Eine andere Problemumgehung:
Auch wenn
ls
mehr Outputls *.txt
erzeugt als produziert (oder Versuche zu produzieren), stößt es nicht auf das "Argument zu lang" -Problem, da Sie keine Argumente an übergebenls
. Beachten Sie, dassgrep
ein regulärer Ausdruck anstelle eines Dateimusters verwendet wird.Vielleicht möchten Sie Folgendes verwenden:
(vorausgesetzt, Ihre Version von
ls
unterstützt diese Option). Dies bedeutet, dassls
die Ausgabe nicht sortiert werden soll, was Zeit und Speicherplatz spart. In diesem Fall spielt die Reihenfolge keine Rolle, da Sie nur Dateien zählen. Der Aufwand zum Sortieren der Ausgabe ist in der Regel gering. In diesem Fall wissen wir jedoch bereits, dass Sie über eine sehr große Anzahl von*.txt
Dateien verfügen .Und Sie sollten überlegen, Ihre Dateien neu zu organisieren, damit Sie nicht so viele Dateien in einem einzigen Verzeichnis haben. Dies kann möglich oder nicht möglich sein.
quelle
MAX_ARG_PAGES scheint ein Kernel-Parameter zu sein. Die Verwendung von
find
undxargs
ist eine typische Kombination, um dieses Limit zu erreichen, aber ich bin nicht sicher, ob es funktionieren wirdwc
.Das Weiterleiten der Ausgabe
find . -name \*\.txt
an eine Datei und das Zählen der Zeilen in dieser Datei sollte als Problemumgehung dienen.quelle
ls
der Ausgabe tun , wird dies nicht lösen. Solange der Platzhalter * .txt über das Limit hinaus erweitert ist, schlägt dies fehl, bevor überhauptls
eine Ausgabe gestartet und generiert wird.ls
sollten Sie angeben-maxdepth 1
, dass die Unterverzeichnisse nicht rekursiv durchsucht werden sollen.Das mag schmutzig sein, aber es entspricht meinen Bedürfnissen und meiner Kompetenz. Ich glaube nicht, dass es sehr schnell geht, aber es hat mir erlaubt, meinen Tag fortzusetzen.
Ich habe eine 90.000-fache Liste von JPEG-Dateien abgerufen und sie an avconv weitergeleitet, um einen Zeitraffer zu generieren.
Ich habe zuvor ls * .jpg | verwendet avconv bevor ich auf dieses Problem stieß.
quelle