Ich habe eine tiefe Verzeichnisstruktur mit einer großen Anzahl von Dateien (ca. 1 Million). Ich möchte einen Befehl gegen jeden ausführen. (In meinem Fall handelt es sich bei den Dateien um PNGs, für die ich optipng ausführen möchte.)
Ich habe das versucht:
find . -name *.png | xargs sudo optipng -o2
aber bekomme den Fehler argument list too long
.
Ich gehe davon aus, dass xargs damit umgehen kann und dass es ein Problem mit meiner Syntax geben muss.
*.png
um ihre Namen - also doppelt , den Zweck des Befehls zu besiegen (nicht alle entsprechenden.png
Dateien und möglicherweise verursacht eineargument list too long
fürfind
sich selbst immer Zitat Dinge , die Sie weitergeben , wie sie ist.:find . -iname '*.png' | ...
Antworten:
Führen Sie die Ausführung direkt mit find und nicht über xargs aus.
quelle
sudo find
mit xargs versucht und es nicht (ich musste das sudo neben xargs stellen) [übrigens nicht meine Gegenstimme]find
wird als root ausgeführt und es erscheint,optipng
was, da es von einem Prozess erzeugt wird, der root gehört, auch als root ausgeführt wird.*.png
. Andernfalls werden PNG-Dateien, die sich im aktuellen Verzeichnis befinden, auf diese erweitert.xargs
Wie Sie sehen, funktioniert es nicht, sudo als Befehl zum Ausführen von zu verwenden . Versuchen Sie es anders herum:Der Unterschied besteht darin, dass Ihre Version einen Befehl wie erstellt
und sudo kann nicht mit so vielen Parametern umgehen.
Wenn Sie es umgekehrt machen, wird sudo einmal ausgeführt, was wiederum startet
xargs
und dann einen Befehl wie generiertund wenn
optipng
viele Dateien als Parameter verarbeitet werden können, sollte es funktionieren.Wenn das immer noch nicht funktioniert, müssen Sie
-exec
stattdessen wie in Geraint's Antwort verwenden, aber dies sollte Ihr letzter Ausweg sein.quelle
argument list too long
nicht sagtoptipng
odersudo
. Ihre einzige Option, wenn Sie wirklich 1 Million Dateien haben, ist die Verwendung-exec
xargs
, dafür zu sorgen, dass dies nicht passiert.-exec
Befehl mit a+
anstelle von a beendet;
wird, gruppiert find die Dateien in Gruppen, die klein genug sind, um den Fehler "Argumentliste zu lang" zu vermeiden. (Sie müssen auch ein{}
Argument vor dem+
angeben, das durch die Dateinamenliste ersetzt wird.) Diese Funktion war nicht im ursprünglichen Unix enthaltenfind
, aber es gibt sie schon lange genug (in POSIX seit über 10 Jahren) ... es ist Zeit zu verlernen die Verwendung vonxargs
.*.png
falls sich im aktuellen Verzeichnis übereinstimmende Dateien befinden.Noch ein Schuss darauf:
find . -name '*.png' | sudo xargs -n x -P y optipng -o2
Dadurch wird eine Option für
x
Dateien undy
solche Prozesse parallel gestartet (dies kann Ihnen helfen, die Dinge schneller zu erledigen, wenn Sie einige Kerne übrig haben). Ein Wert vonx
mehr als 10 hat wahrscheinlich keinen großen Einfluss auf die Leistung.Das wird helfen, die Argumentliste kurz zu halten. Sie könnten also wahrscheinlich dorthin gehen
sudo
, wo Sie es hatten, aber das ist nur ein weiterer Befehl, der für jeden Stapel ausgeführt werden müsste.quelle