Ich habe ungefähr 17k Akten in einem Verzeichnis. Wenn ich renne ls directory
, muss ich ungefähr 15-20 Sekunden warten, bevor die Ergebnisse angezeigt werden. Wenn ich dagegen ls directory | wc -l
oder starte ls directory | grep .xyz
, werden die Ergebnisse sofort angezeigt.
Warum passiert dies und gibt es eine Möglichkeit, dies zu beheben?
Antworten:
Ich gehe davon aus, dass Sie Linux verwenden.
Wenn Ihr
ls
Befehl so ausgerichtet ist, dass er Dateien und Ordner in Farbe anzeigt, muss er die Berechtigungen jedes Elements (einen stat () -Aufruf) ermitteln und feststellen, ob "Dateifunktionen" festgelegt wurden (einen getxattr () -Aufruf) um die richtige Farbe zu wählen. Je nach Dateisystem können diese Aufrufe relativ langsam sein, wenn die erforderlichen Metadaten noch nicht im RAM zwischengespeichert wurden. [Erweiterte Attribute befinden sich häufig im Datenbereich, sodass bei jedem getxattr die Suche auf der Festplatte ausgeführt wird.]Auf der anderen Seite,
ls |
wenn sie auf ein Rohr umgeleitet automatisch deaktiviert Färbung, so dass es nicht mehr irgendwelche zusätzliche Kontrollen tun muss - nur eine einfache readdir () Schleife , die die Dateinamen und Typen zurückgibt, und die Kernel wahrscheinlich sogar Geräte lesen grünes Licht für Das.Normalerweise wird
ls
die Ausgabe in Spalten unterteilt, was bedeutet, dass das gesamte Verzeichnis gelesen werden muss, bevor überhaupt etwas ausgegeben werden kann. Beim Durchlaufen einer Pipe wird der Spaltenmodus automatisch deaktiviert und diese Pufferung wird nicht mehr benötigt. (Die Gesamtlaufzeit muss nicht unbedingt kürzer sein, aber die Ausgabe beginnt früher, sodass sie sich reaktionsschneller anfühlt.)Verwenden Sie
strace
oderperf trace
, um zu überprüfen, welche Systemaufrufe lange dauern.quelle
ls directory | wc -l
erzeugt keine Ausgabe erst nach demls
abschließt. Und selbst wenn Sie auf etwas anderes als ein Terminal schreiben, wird das Verzeichnis standardmäßigls
sortiert , sodass es immer noch nichts ausgeben kann, bevor es das gesamte Verzeichnis gelesen hat.Zwei Dinge:
ls
zuerst undls | wc -l
später ausführen , liest möglicherweise der Erstere Daten von Ihrer Festplatte, und der Letztere liest zwischengespeicherte Daten. In diesem Fall wirdls
zunächst "angehalten" und einige Sekunden lang nichts gedruckt. Ein andererls
Druckvorgang wird fast sofort gestartet, solange die zwischengespeicherten Daten noch vorhanden sind. Wenn Sie mit beginnenls | wc -l
in erster Linie, es würde warten müssen für HDD Daten zu versorgen.stty speed
wird Ihnen etwas Wert zeigen, aber ich denke, dass es für ein virtuelles Terminal keine Rolle spielt. Das Anzeigen von Zeichen und Scrollen nimmt jedoch einige Zeit in Anspruch (siehe diese Frage ). Das Weitergeben derselben Daten durch eine Pipe ist schneller.quelle
ls -C directory > tmp
(Hinzufügen,--color=always
wennls
normalerweise ein Alias für die Verwendung verwendet wird--color
)cat tmp
, undls directory | cat
und schauen Sie sich an, wie lange sie dauern./dev/tty2
. Ich habe ein Verzeichnis mit 200.000 Dateien und muss es nicht einmal gründlich testen. Mit/dev/tty2
dem Befehl scrollen und scrollen und scrollen ... undkonsole
in kürzester Zeit drucken. Geradlinigetime ls
ergab 30s und 1.4S verbunden sind; fürls | wc -l
diese war 0,5s in beiden Terminals. Alle Tests wurden nach der Erstinbetriebnahme durchgeführtls
, bei denen tatsächlich Daten von meiner nicht so schnellen Festplatte abgerufen und vom Betriebssystem zwischengespeichert wurden. Die Ergebnisse sind wiederholbar.