Apa judulnya: apa artinya merangkum variabel dalam {}
,, ""
atau "{}
"? Saya belum bisa menemukan penjelasan daring tentang ini - saya belum bisa merujuknya kecuali menggunakan simbol, yang tidak menghasilkan apa-apa.
Ini sebuah contoh:
declare -a groups
groups+=("CN=exampleexample,OU=exampleexample,OU=exampleexample,DC=example,DC=com")
groups+=("CN=example example,OU=example example,OU=example example,DC=example,DC=com")
Ini:
for group in "${groups[@]}"; do
echo $group
done
Terbukti jauh berbeda dari ini:
for group in $groups; do
echo $group
done
dan ini:
for group in ${groups}; do
echo $group
done
Hanya yang pertama memenuhi apa yang saya inginkan: untuk mengulangi setiap elemen dalam array. Aku tidak benar-benar jelas tentang perbedaan antara $groups
, "$groups"
, ${groups}
dan "${groups}"
. Jika ada yang bisa menjelaskannya, saya akan sangat menghargainya.
Sebagai pertanyaan tambahan - apakah ada yang tahu cara yang diterima untuk merujuk pada enkapsulasi ini?
bash
skrip?Jawaban:
Kawat gigi (
$var
vs${var}
)Dalam kebanyakan kasus,
$var
dan${var}
sama:Kawat gigi hanya diperlukan untuk menyelesaikan ambiguitas dalam ekspresi:
Kutipan (
$var
vs"$var"
vs."${var}"
)Saat Anda menambahkan tanda kutip ganda di sekitar variabel, Anda memberi tahu shell untuk memperlakukannya sebagai satu kata, bahkan jika itu berisi spasi putih:
Bandingkan perilaku itu dengan yang berikut:
Seperti halnya
$var
vs${var}
, kawat gigi hanya diperlukan untuk disambiguasi, misalnya:Perhatikan bahwa
"${var}bar"
dalam contoh kedua di atas juga dapat ditulis"${var}"bar
, dalam hal ini Anda tidak perlu kawat gigi lagi, yaitu"$var"bar
. Namun, jika Anda memiliki banyak kutipan di string Anda, bentuk-bentuk alternatif ini bisa sulit dibaca (dan karenanya sulit dipertahankan). Halaman ini memberikan pengantar yang bagus untuk mengutip dalam Bash.Array (
$var
vs$var[@]
vs.${var[@]}
)Sekarang untuk array Anda. Menurut manual bash :
Dengan kata lain, jika Anda tidak menyediakan indeks
[]
, Anda mendapatkan elemen pertama dari array:Yang persis sama dengan
Untuk mendapatkan semua elemen array, Anda perlu menggunakan
@
sebagai indeks, misalnya${foo[@]}
. Kawat gigi diperlukan dengan array karena tanpa mereka, shell akan memperluas$foo
bagian pertama, memberikan elemen pertama array diikuti oleh literal[@]
:Halaman ini adalah pengantar yang bagus untuk array di Bash.
Kutipan ditinjau kembali (
${foo[@]}
vs."${foo[@]}"
)Anda tidak bertanya tentang ini, tetapi itu adalah perbedaan halus yang perlu diketahui. Jika elemen dalam array Anda bisa berisi spasi putih, Anda perlu menggunakan tanda kutip ganda sehingga setiap elemen diperlakukan sebagai "kata:" yang terpisah.
Bandingkan ini dengan perilaku tanpa tanda kutip ganda:
sumber
${var:?}
yang akan memberikan kesalahan ketika variabel tidak disetel atau tidak disetel. REF: github.com/koalaman/shellcheck/wiki/SC2154${parameter:-word}
,${parameter:=word}
,${parameter#word}
,${parameter/pattern/string}
, dan sebagainya. Saya pikir itu di luar cakupan jawaban ini.TL; DR
Semua contoh yang Anda berikan adalah variasi pada Bash Shell Expansions . Ekspansi terjadi dalam urutan tertentu, dan beberapa memiliki kasus penggunaan khusus.
Kawat gigi sebagai Pembatas Token
The
${var}
sintaks terutama digunakan untuk pembatasan token ambigu. Sebagai contoh, pertimbangkan hal berikut:Kawat Gigi dalam Ekspansi Array
Kawat gigi diperlukan untuk mengakses elemen-elemen dari array dan untuk ekspansi khusus lainnya . Sebagai contoh:
Tokenisasi
Sebagian besar sisa pertanyaan Anda ada hubungannya dengan mengutip, dan bagaimana shell tokenizes input. Pertimbangkan perbedaan dalam bagaimana shell melakukan pemisahan kata dalam contoh-contoh berikut:
The @simbol berinteraksi dengan mengutip berbeda dari *. Secara khusus:
$@
"[e] xpands ke parameter posisi, mulai dari satu. Ketika ekspansi terjadi dalam tanda kutip ganda, setiap parameter diperluas ke kata yang terpisah."${name[*]}
berkembang menjadi satu kata dengan nilai setiap anggota array dipisahkan oleh karakter pertama dari variabel IFS, dan${name[@]}
memperluas setiap elemen nama ke kata yang terpisah."Anda dapat melihat ini dalam tindakan sebagai berikut:
Penggunaan ekspansi yang dikutip sangat penting ketika variabel merujuk pada nilai dengan spasi atau karakter khusus yang dapat mencegah shell dari pemisahan kata dengan cara yang Anda inginkan. Lihat Mengutip untuk lebih lanjut tentang cara mengutip bekerja di Bash.
sumber
Anda perlu membedakan antara array dan variabel sederhana - dan contoh Anda menggunakan array.
Untuk variabel polos:
$var
dan${var}
persis sama."$var"
dan"${var}"
persis sama.Namun, kedua pasangan tidak 100% identik dalam semua kasus. Pertimbangkan output di bawah ini:
Tanpa tanda kutip ganda di sekitar variabel, spasi internal hilang dan ekspansi diperlakukan sebagai dua argumen untuk
printf
perintah. Dengan tanda kutip ganda di sekitar variabel, spasi internal dipertahankan dan ekspansi diperlakukan sebagai satu argumen untukprintf
perintah.Dengan array, aturannya sama dan berbeda.
groups
array, referensi$groups
atau${groups}
sama dengan referensi${groups[0]}
, elemen nol array."${groups[@]}"
adalah analog dengan referensi"$@"
; itu menjaga jarak dalam elemen individual array, dan mengembalikan daftar nilai, satu nilai per elemen array.${groups[@]}
tanpa tanda kutip ganda tidak mempertahankan spasi dan dapat memperkenalkan lebih banyak nilai daripada elemen dalam array jika beberapa elemen mengandung spasi.Sebagai contoh:
Menggunakan
*
alih-alih@
mengarah ke hasil yang sedikit berbeda.Lihat juga Cara mengulang argumen di
bash
skrip .sumber
Kalimat kedua dari paragraf pertama di bawah Parameter Expansion di
man bash
mengatakan,Yang memberi tahu Anda bahwa nama itu hanya kurung kurawal , dan tujuan utamanya adalah untuk menjelaskan di mana nama itu dimulai dan berakhir:
Jika Anda membaca lebih lanjut, Anda menemukan,
Mari kita uji:
Hah. Rapi. Jujur saya tidak tahu itu sebelum menulis ini (saya tidak pernah memiliki lebih dari 9 parameter posisi sebelumnya.)
Tentu saja, Anda juga perlu kawat gigi untuk melakukan fitur ekspansi parameter yang kuat seperti
serta ekspansi array.
sumber
Kasus terkait yang tidak dibahas di atas. Mengutip variabel kosong tampaknya mengubah segalanya
test -n
. Ini secara khusus diberikan sebagai contoh dalaminfo
teks untukcoreutils
, tetapi tidak benar-benar dijelaskan:Saya ingin mendengar penjelasan terperinci. Pengujian saya mengonfirmasi hal ini, dan saya sekarang mengutip variabel saya untuk semua tes string, untuk menghindari
-z
dan-n
mengembalikan hasil yang sama.sumber
Yah, saya tahu bahwa enkapsulasi variabel membantu Anda untuk bekerja dengan sesuatu seperti:
atau sintaksis seperti itu, di mana Anda ingin melakukan sesuatu dengan variabel Anda sebelum mengembalikan nilainya.
Sekarang, jika Anda melihat kode Anda, semua keajaiban ada di dalam
keajaiban ada di sana karena Anda tidak dapat menulis hanya:
$groups[@]
Anda meletakkan variabel Anda di dalam
{}
karena Anda ingin menggunakan karakter khusus[]
dan@
. Anda tidak dapat memberi nama atau memanggil variabel Anda hanya:@
atausomething[]
karena ini adalah karakter khusus untuk operasi dan nama lain.sumber