Saya mencoba untuk memperluas string yang melibatkan wildcard dan koleksi ekstensi yang ditentukan dalam kurung kurawal. Tampaknya tidak ada yang berfungsi seperti contoh di bawah ini. variabel firstList
mengembang dengan baik, tetapi tidak ada secondList
, thirdList
atau fourthList
mengembang dengan baik. Saya juga sudah mencoba berbagai versi eval
tetapi tidak ada yang berhasil juga. Bantuan apa pun akan dihargai
#!/bin/bash
touch a.ext1
touch b.ext1
firstList='*.ext1'
ls $firstList
touch a.ext2
touch b.ext2
secondList='*.{ext1,ext2}'
ls $secondList
ls '$secondList'
ls "$secondList"
thirdList=*.{ext1,ext2}
ls $thirdList
ls '$thirdList'
ls "$thirdList"
fourthList="*.{ext1,ext2}"
ls $fourthList
ls '$fourthList'
ls "$fourthList"
bash
brace-expansion
Leo Simon
sumber
sumber
eval ls $secondList
bekerja dengan baik di sini ... apa yang ingin kamu capai?eval
mendapatkan putaran ke-2 ekspansi.Jawaban:
The shell memperluas
*
hanya jika un-dikutip, setiap mengutip berhenti ekspansi dengan shell.Juga, ekspansi brace perlu tanda kutip untuk diperluas oleh shell.
Karya ini (mari kita gunakan gema untuk melihat apa yang dilakukan shell):
Bahkan jika ada file dengan beberapa nama lain:
Mengapa itu berhasil?
Penting bagi kita untuk memahami mengapa itu berhasil. Itu karena urutan ekspansi. Pertama "ekspansi Brace" dan kemudian (yang terakhir) "Pathname Expansion" (alias glob-expansion).
Kami dapat mematikan "Perluasan jalur" sejenak:
"Perluasan Pathname" menerima dua argumen:
*.ext1
dan*.ext2
.Masalahnya adalah kita tidak bisa menggunakan variabel untuk ekspansi brace.
Telah dijelaskan beberapa kali sebelumnya untuk menggunakan variabel di dalam "Ekspansi Brace"
Untuk memperluas "Ekspansi Brace" yang merupakan hasil dari "Ekspansi Variabel", Anda harus mengirimkan kembali baris perintah ke shell dengan
eval
.Nilai nama file tidak menimbulkan masalah eksekusi untuk eval:
Tetapi nilai dari
$list
bisa tidak aman. Namun, nilai$list
diatur oleh penulis skrip. Penulis skrip mengendalikaneval
: Hanya saja jangan gunakan nilai yang ditetapkan secara eksternal untuk$list
. Coba ini:Alternatif yang lebih baik.
Alternatif (tanpa eval) adalah menggunakan Bash "Extended Patterns" :
Catatan: Perlu diketahui bahwa kedua solusi (eval dan pola) (seperti tertulis) aman untuk nama file dengan spasi atau baris baru. Tetapi akan gagal untuk
$list
dengan spasi, karena$list
tanda kutip atau tanda kutip menghapus tanda kutip.sumber
Mempertimbangkan:
Masalahnya adalah ekspansi brace dilakukan sebelum ekspansi variabel . Itu berarti bahwa, di atas, ekspansi brace tidak pernah dilakukan.
Ini karena, ketika bash pertama kali melihat baris perintah, tidak ada kawat gigi. Setelah
secondList
diperluas, sudah terlambat.Berikut ini akan berfungsi:
Di sini, baris perintah memiliki kawat gigi sehingga ekspansi kawat gigi dapat dilakukan sebagai langkah pertama. Setelah itu, nilai
$s
substitusi dalam ( ekspansi variabel ), dan ekspansi pathname terakhir dilakukan.Dokumentasi
man bash
menjelaskan urutan ekspansi:sumber