Ich benutze den folgenden Befehl:
\cp -uf /home/ftpuser1/public_html/ftparea/*.jpg /home/ftpuser2/public_html/ftparea/
Und ich bekomme den Fehler:
-bash: /bin/cp: Argument list too long
Ich habe auch versucht:
ls /home/ftpuser1/public_html/ftparea/*.jpg | xargs -I {} cp -uf {} /home/ftpuser2/public_html/ftparea/
Ich habe immer noch -bash: / bin / ls: Argumentliste zu lang
Irgendwelche Ideen?
linux
bash
unix-shell
icelizard
quelle
quelle
ls
ist nicht dafür ausgelegt. Verwenden Siefind
.ls
vor allem nicht dafür ausgelegt: mywiki.wooledge.org/ParsingLsAntworten:
* .jpg wird zu einer Liste erweitert, die länger ist, als die Shell verarbeiten kann. Versuchen Sie dies stattdessen
quelle
Es gibt eine maximale Begrenzung für die Länge einer Argumentliste für Systembefehle. Diese Begrenzung ist distro-spezifisch und basiert auf dem Wert, zu
MAX_ARG_PAGES
dem der Kernel kompiliert wurde. Sie kann nicht geändert werden, ohne den Kernel neu zu kompilieren.Aufgrund der Art und Weise, wie Globbing von der Shell verarbeitet wird, wirkt sich dies auf die meisten Systembefehle aus, wenn Sie dasselbe Argument ("* .jpg") verwenden. Da der Glob zuerst von der Shell verarbeitet und dann an den Befehl gesendet wird, lautet der Befehl:
ist im Wesentlichen das gleiche für die Shell, als ob Sie geschrieben haben:
Wenn Sie mit vielen JPEGs zu tun haben, kann dies sehr schnell unüberschaubar werden. Abhängig von Ihrer Namenskonvention und der Anzahl der Dateien, die Sie tatsächlich verarbeiten müssen, können Sie den Befehl cp jeweils für eine andere Teilmenge des Verzeichnisses ausführen :
Dies könnte funktionieren, aber wie effektiv es wäre, hängt davon ab, wie gut Sie Ihre Dateiliste in praktische globbable Blöcke aufteilen können.
Globbable. Ich mag dieses Wort.
Einige Befehle, wie find und xargs , können große Dateilisten verarbeiten, ohne schmerzhaft große Argumentlisten zu erstellen.
Das Argument -exec führt den Rest der Befehlszeile einmal für jede von find gefundene Datei aus und ersetzt das {} durch jeden gefundenen Dateinamen. Da der Befehl cp jeweils nur für eine Datei ausgeführt wird, ist das Argumentlistenlimit kein Problem.
Dies kann langsam sein, da jede Datei einzeln verarbeitet werden muss. Die Verwendung von xargs könnte eine effizientere Lösung bieten:
xargs kann die vollständige Dateiliste von find in Argumentlisten mit überschaubaren Größen aufteilen und cp für jede dieser Unterlisten ausführen .
Natürlich gibt es auch die Möglichkeit, den Kernel einfach neu zu kompilieren und einen größeren Wert für festzulegen
MAX_ARG_PAGES
. Das Neukompilieren eines Kernels ist jedoch mehr Arbeit, als ich in dieser Antwort erklären möchte.quelle
xargs
scheint viel effizienter zu sein, da die resultierende Anzahl von Befehlsaufrufen viel kleiner ist. In meinem Fall sehe ich eine 6-12-mal bessere Leistung bei der Verwendungargs
als bei Verwendung einer-exec
Lösung mit wachsender Anzahl von Dateien, da die Effizienz steigt.Dies liegt daran, dass Ihr Platzhalterausdruck (
*.jpg
) beim Erweitern das Längenlimit für Befehlszeilenargumente überschreitet (wahrscheinlich, weil Sie viele JPG-Dateien unter haben/home/ftpuser/public_html/ftparea
).Es gibt verschiedene Möglichkeiten, diese Einschränkung zu umgehen, z. B.
find
oderxargs
. In diesem Artikel finden Sie weitere Informationen dazu.quelle
Es gibt eine maximale Anzahl von Argumenten, die für ein Programm angegeben werden können. Bash erweitert * .jpg auf viele Argumente für cp. Sie können es mit find, xargs oder rsync usw. lösen.
Schauen Sie hier über xargs und finden Sie
/programming/143171/how-can-i-use-xargs-to-copy-files-that-have-spaces-and-quotes-in-their-names
quelle
Wie GoldPseudo kommentierte, gibt es eine Begrenzung für die Anzahl der Argumente, die Sie an einen Prozess übergeben können, den Sie erzeugen. In seiner Antwort finden Sie eine gute Beschreibung dieses Parameters.
Sie können das Problem vermeiden, indem Sie entweder nicht zu viele Argumente übergeben oder die Anzahl der übergebenen Argumente verringern.
Eine for-Schleife in der Shell, find und ls, grep und eine while-Schleife machen in dieser Situation alle dasselbe -
und
und
Alle haben ein Programm, das das Verzeichnis liest (die Shell selbst, find und ls), und ein anderes Programm, das tatsächlich ein Argument pro Ausführung akzeptiert und die gesamte Befehlsliste durchläuft.
Dies ist nun langsam, da der RM für jede Datei, die dem * .jpg-Muster entspricht, gegabelt und ausgeführt werden muss.
Hier kommt xargs ins Spiel. xargs verwendet Standardeingaben und erzeugt für jede N-Zeile (für freebsd sind es standardmäßig 5000) ein Programm mit N Argumenten. xargs ist eine Optimierung der obigen Schleifen, da Sie nur 1 / N-Programme teilen müssen, um über den gesamten Satz von Dateien zu iterieren, die Argumente von der Befehlszeile lesen.
quelle
Der '*' Glob wird auf zu viele Dateinamen erweitert. Verwenden Sie stattdessen find / home / ftpuser / public_html -name '* .jpg'.
quelle
Wenn Sie die
+
Option verwenden,find -exec
wird der Vorgang erheblich beschleunigt.Die
+
Option muss{}
das letzte Argument sein, damit die Funktion-t /your/destination
(oder--target-directory=/your/destination
)cp
funktioniert.Von
man find
:Bearbeiten : Argumente in cp neu angeordnet
quelle
cp
, um diesen Fehler zu beheben.Es hört sich so an, als hätten Sie zu viele
*.jpg
Dateien in diesem Verzeichnis, um sie alle gleichzeitig in die Befehlszeile zu stellen. Du könntest es versuchen:Möglicherweise müssen Sie
man xargs
Ihre Implementierung überprüfen , um festzustellen, ob der-I
Switch für Ihr System korrekt ist.Wollen Sie diese Dateien wirklich an denselben Speicherort kopieren, an dem sie sich bereits befinden?
quelle
ls
wird das gleiche Problem haben! Ich habe zu dem gewechselt,find
was nicht wird.Gehe zum Ordner
und führen Sie Folgendes aus:
Auf diese Weise kann sich der Ordner 'ftparea' negativ auswirken, wenn Sie nur die '* .jpg'-Dateien daraus haben möchten. Wenn jedoch keine Unterordner vorhanden sind, ist dieser Ansatz definitiv viel schneller als mit find und xargs
quelle