Mengapa 'find -exec cmd {} +' harus diakhiri dengan '{} +'?

11

Pendahuluan: Saya mengerti perbedaan antara -exec {} \;& -exec {} +. Saya juga tidak punya masalah seperti itu , saya hanya ingin tahu tentang semantik find.


Saat mengakhiri -execargumen dengan +alih - alih ;, kita perlu mengakhiri ini dengan {} +, misalnya:

# FreeBSD find
$ find . -type f -exec cp {} /tmp +
find: -exec: no terminating ";" or "+"

# GNU find is even more cryptic:
$ find: missing argument to `-exec'

Menggunakan ;dalam contoh-contoh ini bukannya +berfungsi dengan baik (tapi jelas melakukan sesuatu yang lain).

Dari POSIX :

-exec utility_name [argument ...] ;
-exec utility_name [argument ...] {} +

... Hanya <plus-sign> yang segera mengikuti argumen yang hanya berisi dua karakter " {}" yang akan menandai akhir dari ekspresi utama. Penggunaan lain dari <plus-sign> tidak akan diperlakukan sebagai khusus.

Dengan kata lain, saat menggunakan +, perintah harus diakhiri dengan {} +.

Kenapa ini? Dan mengapa hanya dengan +dan bukan ;? Pada awalnya saya pikir mungkin untuk menghindari konflik dengan nama file yang mengandung +, tetapi nama file dengan ;tampaknya berfungsi dengan baik? Saya merasa sulit untuk percaya batasan ini sewenang-wenang ...

Martin Tournoij
sumber
3
FWIW, halaman POSIX juga mengatakan itu The "-exec ... {} +" syntax adopted was a result of IEEE PASC Interpretation 1003.2 #210dan dalam dokumen itu Anda akan menemukan rincian lebih lanjut, misalnya:Note that the "+" is only treated as special if it immediately follows "{}". This minimises the chances of causing problems with existing uses of "+" as an argument with "-exec".
don_crissti

Jawaban:

5

The pemikiran yang diberikan dalam spesifikasi POSIX adalah:

The "-exec ... {} +"sintaks diadopsi adalah hasil dari IEEE PASC Interpretasi 1003,2 # 210. Perlu dicatat bahwa ini adalah perubahan yang tidak sesuai dengan standar ISO / IEC 9899: 1999. Sebagai contoh, perintah berikut mencetak semua file dengan '-'setelah nama mereka jika mereka adalah file biasa, dan '+'sebaliknya:

find / -type f -exec echo {} - ';' -o -exec echo {} + ';'

Perubahan ini membatalkan penggunaan seperti ini. Meskipun standar sebelumnya menyatakan bahwa penggunaan ini akan berhasil, dalam praktiknya banyak yang tidak mendukungnya dan pengembang standar merasa lebih baik untuk sekarang menyatakan bahwa ini tidak diperbolehkan.

Interpretasi PASC 1003.2 # 210 lebih detail tentang sejarah -exec … {} +. Itu ada pada beberapa sistem Unix sebelum diadopsi oleh POSIX; laporan cacat melacaknya kembali ke SVR4 (di mana sebagian besar tidak berdokumen). Laporan cacat membenarkan perubahan yang tidak kompatibel sebagai berdampak kecil dalam praktik:

Perhatikan bahwa "+" hanya diperlakukan sebagai istimewa jika segera mengikuti "{}". Ini meminimalkan kemungkinan menyebabkan masalah dengan penggunaan "+" yang ada sebagai argumen dengan "-exec".

Meskipun menambahkan dukungan untuk -exec … {} +akan merusak beberapa aplikasi yang sesuai seperti contoh di atas, ada lebih sedikit dari ini daripada jika -exec … {} … +diizinkan.

Alasan lain, mungkin, untuk membatasi {}menjadi argumen terakhir adalah kemudahan implementasi. Jika {}diizinkan di mana saja dalam daftar argumen -exec, findprogram harus membuat baris perintah dengan menyalin argumen statis, lalu bagian variabel, lalu bagian statis lainnya. Ini akan membuat lebih sulit untuk membangun daftar argumen dan memperhitungkan batas ukuran. Kesulitannya minimal, tetapi pelaksana suka memotong sudut. Mendukung banyak contoh yang dapat diganti {}(jika -exec {} foo +berfungsi, dapat diharapkan secara logis -exec {} foo {} +juga) akan jauh lebih sulit.

Gilles 'SANGAT berhenti menjadi jahat'
sumber