GNU/Linux >> Belajar Linux >  >> Linux

Daftar argumen kesalahan terlalu panjang untuk perintah rm, cp, mv

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

Linux
  1. Lembar contekan untuk perintah umum Linux

  2. Linux menemukan perintah

  3. Contoh Bash untuk loop

  1. Bagaimana cara membatasi kedalaman untuk daftar file rekursif?

  2. Kesalahan SFTP Pesan yang diterima terlalu lama

  3. bash:/bin/tar:Daftar argumen terlalu panjang saat mengompresi banyak file dengan tar

  1. 10 Perintah Linux Untuk Diagnostik Jaringan

  2. ps:perintah penuh terlalu panjang

  3. Bagaimana saya bisa menghapus semua file dari direktori ketika melaporkan daftar Argumen terlalu lama