Penggunaan melampirkan kurung {} sebagai argumen untuk perintah dan opsinya

11

Contohnya

Saya baru-baru ini menemukan contoh penggunaan pasang kurung kurawal {}, dengan tidak ada di antara kurung buka dan tutup, sebagai argumen untuk perintah dan bahkan untuk pilihan mereka:

cat foo | xargs -I{} echo {}

find . -size 0 -exec rm -i {} \;

Tidak Ada Dokumentasi

Masalah saya adalah bahwa saya tidak dapat menemukan dokumentasi di Manual Bash GNU yang menjelaskan penggunaan {}dalam konteks seperti pada contoh di atas.

Saya tidak berpikir itu adalah ekspansi parameter , karena tanda dolar harus mendahului kurung kurawal dalam ekspansi parameter seperti pada ${}.

Ini tidak bisa menjadi ekspansi penjepit baik, karena mengambil bentuk {x..y[..incr]}, di mana xdan ytidak opsional.

Itu juga tidak bisa menjadi pengelompokan perintah , karena {}digunakan sebagai argumen.

Pertanyaan

  1. Apa arti sepasang kawat gigi penutup {}, secara umum, sebagai argumen untuk perintah apa pun yang menerimanya?

  2. Di mana saya dapat menemukan dokumentasi yang menjelaskan penggunaan {}sebagai argumen?

Niko Gambt
sumber
Beberapa perintah memiliki opsi ini {}- artinya targetsuntuk bertindak, dengan findperintah, ini menghapus / rmmenemukan file.
Tuyen Pham

Jawaban:

16

Kurung kurawal ini dibiarkan sendiri oleh bash; mereka milik finddan xargs, masing-masing, dan dijelaskan dalam halaman manual mereka.

man find

-exec perintah ;

Jalankan perintah ; true jika 0 status dikembalikan. Semua argumen berikut untuk ditemukan dianggap sebagai argumen untuk perintah sampai argumen yang terdiri dari ;ditemui. String {}diganti dengan nama file saat ini sedang diproses di mana-mana itu terjadi dalam argumen ke perintah, bukan hanya dalam argumen di mana itu sendirian, seperti dalam beberapa versi find. Kedua konstruksi ini mungkin perlu diloloskan (dengan a \) atau dikutip untuk melindunginya dari ekspansi oleh shell. Lihat bagian CONTOH untuk contoh penggunaan -execopsi. Perintah yang ditentukan dijalankan sekali untuk setiap file yang cocok. Perintah dijalankan di direktori awal. Ada masalah keamanan yang tidak dapat dihindari seputar penggunaan -exec tindakan; Anda harus menggunakan -execdiropsi ini sebagai gantinya.

-exec perintah {} +

Varian -execaksi ini menjalankan perintah yang ditentukan pada file yang dipilih, tetapi baris perintah dibangun dengan menambahkan setiap nama file yang dipilih di akhir; jumlah total doa perintah akan jauh lebih sedikit daripada jumlah file yang cocok. Baris perintah dibangun dengan cara yang sama dengan yang xargsmembangun baris perintahnya. Hanya satu instance dari {}yang diizinkan dalam perintah. Perintah dijalankan di direktori awal. Jika findmenemukan kesalahan, ini kadang-kadang dapat menyebabkan keluar langsung, sehingga beberapa perintah yang tertunda mungkin tidak dijalankan sama sekali. Varian ini -execselalu menghasilkan true.

-execdir perintah ;

-execdir perintah {} +

Suka -exec, tetapi perintah yang ditentukan dijalankan dari subdirektori yang berisi file yang cocok, yang biasanya bukan direktori tempat Anda mulai mencari. Ini metode yang jauh lebih aman untuk menjalankan perintah, karena menghindari kondisi balapan selama resolusi jalur ke file yang cocok. Seperti -exec tindakan, + bentuk -execdir akan membangun baris perintah untuk memproses lebih dari satu file yang cocok, tetapi setiap permintaan perintah yang diberikan hanya akan mencantumkan file yang ada di subdirektori yang sama. Jika Anda menggunakan opsi ini, Anda harus memastikan bahwa $PATHvariabel lingkungan Anda tidak referensi.; jika tidak, penyerang dapat menjalankan perintah apa pun yang mereka suka dengan meninggalkan file dengan nama yang sesuai di direktori di mana Anda akan menjalankan -execdir. Hal yang sama berlaku untuk memiliki entri $PATHyang kosong atau yang bukan nama direktori absolut. Jika findmenemukan kesalahan, ini kadang-kadang dapat menyebabkan keluar langsung, sehingga beberapa perintah yang tertunda mungkin tidak dijalankan sama sekali. Hasil dari tindakan tergantung pada apakah varian +atau ;sedang digunakan; -execdir perintah {} + selalu mengembalikan true, sedangkan -execdir perintah {} ; mengembalikan true hanya jika perintah mengembalikan 0.

man xargs

-I ganti-str

Ganti kemunculan replace-str dalam argumen-awal dengan nama yang dibaca dari input standar. Juga, blanko tanda kutip tidak menghentikan item input; sebaliknya pemisah adalah karakter baris baru. Tersirat -xdan -L 1.

-i[ ganti-str ], --replace[ =ganti-str ]

Opsi ini adalah sinonim untuk -Ireplace-str jika replace-str ditentukan. Jika argumen replace-str tidak ada, efeknya sama dengan -I{}. Opsi ini sudah usang; gunakan -Isaja.

Sunting: dan di sini MENGAPA bash mengabaikan kurung kurawal itu:

man bash

{ daftar; }

daftar hanya dieksekusi di lingkungan shell saat ini. daftar harus diakhiri dengan baris baru atau titik koma. Ini dikenal sebagai perintah grup. Status kembali adalah status keluar dari daftar. Perhatikan bahwa tidak seperti metacharacters ( dan ) , { dan } adalah kata-kata yang dicadangkan dan harus muncul ketika kata yang dilindungi diizinkan untuk dikenali. Karena mereka tidak menyebabkan istirahat kata, mereka harus dipisahkan dari daftar oleh spasi putih atau karakter meta shell lainnya.

Untuk penekanan: daftar harus diakhiri dengan baris baru atau titik koma .

Tink
sumber
1
Terima kasih! Saya kesal bahwa siapa pun yang menulis man xargsbahkan tidak repot-repot menjelaskan apa yang {}sebenarnya berarti, juga penulis tidak mengarahkan (tidak ada kata pun dimaksudkan) pembaca untuk penjelasan -execdi halaman manual find.
Niko Gambt
@NikoGambt - Saya bersimpati ...
tink
5
@NikoGambt Yah, {} tidak benar-benar berarti apa pun untuk xargs, kecuali menjadi nilai default untuk -i, yang sudah usang. Saya tidak yakin penjelasan apa yang diperlukan di luar itu. Dalam contoh yang Anda posting, mungkin juga xargs -Iab echo ab; itu adalah pilihan murni yang sewenang-wenang.
Random832
@ Random832 Setelah melakukan beberapa pengujian lagi -I, saya sekarang mengerti apa yang sebenarnya dilakukan opsi itu. Ya, {}sewenang-wenang, seperti yang Anda katakan. Saya hanya bingung dengan penjelasannya If the replace-str argument is missing, the effect is the same as -I{}. Jika -Itanpa argumen sama dengan -I{}, maka cat foo | xargs -I echo {}akan menghasilkan hasil yang sama dengan berlari cat foo | xargs -I{} echo {}. Namun, keduanya tidak sama. Yang pertama adalah kesalahan, dan yang lebih membingungkan saya adalah pesan kesalahan xargs: {}: No such file or directory, tapi itu hanya karena implementasi.
Niko Gambt
1
@NikoGambt -I(huruf besar I) tidak dapat dijalankan tanpa argumen. Argumennya -Iadalah echo. Ini adalah perbedaan utama antara -Idan -i(dan alasan -i sudah usang, karena opsi dengan argumen yang tidak diperlukan jarang dan membingungkan)
Random832