Jawaban lain adalah dengan memaksa xargs untuk memproses perintah dalam batch. Misalnya ke delete file 100 sekaligus, cd ke dalam direktori dan jalankan ini:
echo *.pdf | xargs -n 100 rm
tl;dr
Ini adalah batasan kernel pada ukuran argumen baris perintah. Gunakan for sebagai gantinya.
Asal masalah
Ini adalah masalah sistem, terkait dengan execve dan ARG_MAX konstan. Ada banyak dokumentasi tentang itu (lihat man execve, wiki debian, detail ARG_MAX).
Pada dasarnya, perluasan menghasilkan perintah (dengan parameternya) yang melebihi ARG_MAX limit.Pada kernel 2.6.23 , batas ditetapkan pada 128 kB . Konstanta ini telah ditingkatkan dan Anda bisa mendapatkan nilainya dengan menjalankan:
getconf ARG_MAX
# 2097152 # on 3.5.0-40-generic
Solusi:Menggunakan for Lingkaran
Gunakan for loop seperti yang direkomendasikan di BashFAQ/095 dan tidak ada batasan kecuali RAM/ruang memori:
Uji coba untuk memastikan itu akan menghapus apa yang Anda harapkan:
for f in *.pdf; do echo rm "$f"; done
Dan jalankan:
for f in *.pdf; do rm "$f"; done
Ini juga merupakan pendekatan portabel karena glob memiliki perilaku yang kuat dan konsisten di antara shell (bagian dari spesifikasi POSIX).
Catatan: Seperti dicatat oleh beberapa komentar, ini memang lebih lambat tetapi lebih dapat dipertahankan karena dapat mengadaptasi skenario yang lebih kompleks, mis. di mana seseorang ingin melakukan lebih dari satu tindakan.
Solusi:Menggunakan find
Jika Anda bersikeras, Anda dapat menggunakan find tapi benar-benar jangan gunakan xargs karena "berbahaya (rusak, dapat dieksploitasi, dll.) saat membaca input yang tidak dibatasi NUL" :
find . -maxdepth 1 -name '*.pdf' -delete
Menggunakan -maxdepth 1 ... -delete bukannya -exec rm {} + memungkinkan find untuk sekadar menjalankan panggilan sistem yang diperlukan itu sendiri tanpa menggunakan proses eksternal, sehingga lebih cepat (berkat komentar @chepner).
Referensi
- Saya mendapatkan "Daftar argumen terlalu panjang". Bagaimana saya bisa memproses daftar besar dalam potongan? @ wooledge
- execve(2) - halaman manual Linux (mencari ARG_MAX);
- Kesalahan:Daftar argumen terlalu panjang @ wiki Debian;
- Mengapa saya mendapatkan “/bin/sh:Argument list too long” saat meneruskan argumen yang dikutip? @ Pengguna Super
find memiliki -delete tindakan:
find . -maxdepth 1 -name '*.pdf' -delete
Alasan mengapa hal ini terjadi adalah karena bash sebenarnya memperluas tanda bintang ke setiap file yang cocok, menghasilkan baris perintah yang sangat panjang.
Coba ini:
find . -name "*.pdf" -print0 | xargs -0 rm
Peringatan: ini adalah pencarian rekursif dan akan menemukan (dan menghapus) file di subdirektori juga. Tempelkan -f ke perintah rm hanya jika Anda yakin tidak ingin konfirmasi.
Anda dapat melakukan hal berikut untuk membuat perintah non-rekursif:
find . -maxdepth 1 -name "*.pdf" -print0 | xargs -0 rm
Pilihan lainnya adalah menggunakan -delete find bendera:
find . -name "*.pdf" -delete