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):
$ echo *.{ext1,ext2}
a.ext1 b.ext1 a.ext2 b.ext2
Bahkan jika ada file dengan beberapa nama lain:
$ touch {a,b}.{ext1,ext2} {c,d}.{ext3,ext4} none
ls
a.ext1 a.ext2 b.ext1 b.ext2 c.ext3 c.ext4 d.ext3 d.ext4 none
$ echo *.{ext1,ext2}
a.ext1 b.ext1 a.ext2 b.ext2
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).
Brace --> Parameter (variable) --> Pathname
Kami dapat mematikan "Perluasan jalur" sejenak:
$ set -f
$ echo *.{ext1,ext2}
*.ext1 *.ext2
"Perluasan Pathname" menerima dua argumen: *.ext1
dan *.ext2
.
$ set +f
$ echo *.{ext1,ext2}
a.ext1 b.ext1 a.ext2 b.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
.
$ list={ext1,ext2}
$ eval echo '*.'"$list"
Penjepit -> Variabel -> Glob || -> Brace -> Variabel -> Glob
........ dikutip di sini -> ^^^^^^ || eval ^^^^^^^^^^^^^^^^^^^^^^^^^
Nilai nama file tidak menimbulkan masalah eksekusi untuk eval:
$ touch 'a;date;.ext1'
eval echo '*.'"$list"
a;date;.ext1 a.ext1 b.ext1 a.ext2 b.ext2
Tetapi nilai dari $list
bisa tidak aman. Namun, nilai $list
diatur oleh penulis skrip. Penulis skrip mengendalikan eval
: Hanya saja jangan gunakan nilai yang ditetapkan secara eksternal untuk $list
. Coba ini:
#!/bin/bash
touch {a,b,c}.ext{1,2}
list=ext{1,2}
eval ls -l -- '*.'"$list"
Alternatif yang lebih baik.
Alternatif (tanpa eval) adalah menggunakan Bash "Extended Patterns" :
#!/bin/bash
shopt -s extglob
list='@(ext1|ext2)'
ls -- *.$list
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.
eval ls $secondList
bekerja dengan baik di sini ... apa yang ingin kamu capai?