Saya menggunakan perintah berikut:
\cp -uf /home/ftpuser1/public_html/ftparea/*.jpg /home/ftpuser2/public_html/ftparea/
Dan saya mendapatkan kesalahan:
-bash: /bin/cp: Argument list too long
Saya juga sudah mencoba:
ls /home/ftpuser1/public_html/ftparea/*.jpg | xargs -I {} cp -uf {} /home/ftpuser2/public_html/ftparea/
Masih punya -bash: / bin / ls: Daftar argumen terlalu panjang
Ide saya?
linux
bash
unix-shell
icelizard
sumber
sumber
ls
tidak dirancang untuk melakukan hal semacam ini. Gunakanfind
.ls
ini terutama tidak dirancang untuk melakukan hal ini: mywiki.wooledge.org/ParsingLsJawaban:
* .jpg meluas ke daftar lebih lama daripada yang bisa ditangani shell. Coba ini sebagai gantinya
sumber
Ada batas maksimum untuk berapa lama daftar argumen bisa untuk perintah sistem - batas ini adalah distro-spesifik berdasarkan nilai
MAX_ARG_PAGES
ketika kernel dikompilasi, dan tidak dapat diubah tanpa mengkompilasi ulang kernel.Karena cara globbing ditangani oleh shell, ini akan memengaruhi sebagian besar perintah sistem saat Anda menggunakan argumen yang sama ("* .jpg"). Karena glob diproses oleh shell terlebih dahulu, dan kemudian dikirim ke perintah, perintah:
pada dasarnya sama dengan shell seolah-olah Anda menulis:
Jika Anda berurusan dengan banyak jpeg, ini bisa menjadi tidak terkelola dengan sangat cepat. Bergantung pada konvensi penamaan Anda dan jumlah file yang sebenarnya harus Anda proses, Anda dapat menjalankan perintah cp pada subset direktori yang berbeda secara bersamaan:
Ini bisa berhasil, tetapi seberapa efektif itu akan didasarkan pada seberapa baik Anda dapat memecah daftar file Anda menjadi blok globbable nyaman.
Globbable. Saya suka kata itu.
Beberapa perintah, seperti find dan xargs , dapat menangani daftar file besar tanpa membuat daftar argumen dengan ukuran yang menyakitkan.
Argumen -exec akan menjalankan sisa baris perintah satu kali untuk setiap file yang ditemukan oleh find , menggantikan {} dengan setiap nama file yang ditemukan. Karena perintah cp hanya dijalankan pada satu file pada satu waktu, batas daftar argumen tidak menjadi masalah.
Ini mungkin lambat karena harus memproses setiap file secara individual. Menggunakan xargs dapat memberikan solusi yang lebih efisien:
xargs dapat mengambil daftar file lengkap yang disediakan oleh find , dan memecahnya menjadi daftar argumen ukuran yang dapat dikelola dan menjalankan cp pada masing-masing sublists tersebut.
Tentu saja, ada juga kemungkinan hanya mengkompilasi ulang kernel Anda, menetapkan nilai yang lebih besar
MAX_ARG_PAGES
. Tetapi mengkompilasi ulang kernel lebih berhasil daripada yang saya ingin jelaskan dalam jawaban ini.sumber
xargs
tampaknya jauh lebih efisien, karena jumlah panggilan perintah yang dihasilkan jauh lebih kecil. Dalam kasus saya, saya melihat kinerja 6-12 kali lebih baik ketika menggunakanargs
kemudian ketika menggunakan-exec
solusi dengan semakin banyak file adalah efisiensi yang semakin meningkat.Itu terjadi karena ekspresi wildcard Anda (
*.jpg
) melebihi batas panjang argumen baris perintah ketika diperluas (mungkin karena Anda memiliki banyak file .jpg di bawah/home/ftpuser/public_html/ftparea
).Ada beberapa cara untuk menghindari batasan itu, seperti menggunakan
find
atauxargs
. Lihat artikel ini untuk detail lebih lanjut tentang cara melakukannya.sumber
Seperti yang dikomentari GoldPseudo, ada batasan berapa banyak argumen yang dapat Anda berikan pada proses yang Anda hasilkan. Lihat jawabannya untuk deskripsi yang baik tentang parameter itu.
Anda dapat menghindari masalah dengan tidak melewati proses terlalu banyak argumen atau dengan mengurangi jumlah argumen yang Anda lewati.
A untuk loop di shell, find, dan ls, grep, dan loop sementara semua melakukan hal yang sama dalam situasi ini -
dan
dan
semua memiliki satu program yang membaca direktori (shell itu sendiri, menemukan, dan ls) dan program lain yang benar-benar mengambil satu argumen per eksekusi dan mengulangi seluruh daftar perintah.
Sekarang, ini akan lambat karena rm perlu bercabang dan dieksekusi untuk setiap file yang cocok dengan pola * .jpg.
Di sinilah xargs berperan. xargs mengambil input standar dan untuk setiap N (untuk freebsd secara default 5000) baris, ia memunculkan satu program dengan argumen N. xargs adalah optimasi dari loop di atas karena Anda hanya perlu memotong program 1 / N untuk beralih ke seluruh rangkaian file yang membaca argumen dari baris perintah.
sumber
Ada jumlah maksimum argumen yang dapat ditentukan untuk suatu program, bash memperluas * .jpg ke banyak argumen ke cp. Anda dapat menyelesaikannya dengan menggunakan find, xargs atau rsync dll.
Lihat di sini tentang xargs dan temukan
/programming/143171/how-can-i-use-xargs-to-copy-files-that-have-spaces-and-quotes-in-their-names
sumber
Glob '*' meluas ke terlalu banyak nama file. Gunakan find / home / ftpuser / public_html -name '* .jpg'.
sumber
Menggunakan
+
opsi untukfind -exec
akan sangat mempercepat operasi.The
+
opsi membutuhkan{}
untuk menjadi argumen terakhir sehingga menggunakan-t /your/destination
(atau--target-directory=/your/destination
) pilihan untukcp
merek bekerja.Dari
man find
:Sunting : mengatur ulang argumen ke cp
sumber
cp
untuk memperbaiki kesalahan itu.Sepertinya Anda memiliki terlalu banyak
*.jpg
file di direktori itu untuk meletakkan semuanya di baris perintah sekaligus. Kamu bisa mencoba:Anda mungkin perlu memeriksa
man xargs
implementasi Anda untuk melihat apakah-I
switch sudah benar untuk sistem Anda.Sebenarnya, apakah Anda benar-benar berniat untuk menyalin file-file itu ke lokasi yang sama dengan yang sudah ada?
sumber
ls
akan memiliki masalah yang sama! Saya sudah berubah menjadifind
tidak mau.Buka folder
dan jalankan yang berikut ini:
Dengan cara ini jika folder 'ftparea' memiliki subfolder, ini mungkin efek negatif jika Anda hanya menginginkan file '* .jpg' dari itu, tetapi jika tidak ada subfolder, pendekatan ini pasti akan jauh lebih cepat daripada menggunakan find dan xargs
sumber