Saya bisa menulis
VAR=$VAR1
VAR=${VAR1}
VAR="$VAR1"
VAR="${VAR1}"
hasil akhirnya bagi saya semua tampak hampir sama. Mengapa saya harus menulis yang satu atau yang lain? apakah semua ini tidak portabel / POSIX?
sumber
Saya bisa menulis
VAR=$VAR1
VAR=${VAR1}
VAR="$VAR1"
VAR="${VAR1}"
hasil akhirnya bagi saya semua tampak hampir sama. Mengapa saya harus menulis yang satu atau yang lain? apakah semua ini tidak portabel / POSIX?
VAR=$VAR1
adalah versi sederhana dari VAR=${VAR1}
. Ada hal-hal yang kedua dapat lakukan yang pertama tidak bisa, misalnya referensi indeks array (tidak portabel) atau menghapus substring (POSIX-portable). Lihat bagian Lebih lanjut tentang variabel pada Panduan Bash untuk Pemula dan Ekspansi Parameter dalam spesifikasi POSIX.
Menggunakan tanda kutip di sekitar variabel sebagai rm -- "$VAR1"
atau rm -- "${VAR}"
adalah ide yang baik. Ini menjadikan isi variabel sebagai unit atom. Jika nilai variabel berisi kosong (well, karakter dalam $IFS
variabel khusus, kosong secara default) atau karakter globbing dan Anda tidak mengutipnya, maka setiap kata dipertimbangkan untuk pembuatan nama file (globbing) yang perluasannya membuat banyak argumen untuk apa pun yang Anda sedang dilakukan.
$ find .
.
./*r*
./-rf
./another
./filename
./spaced filename
./another spaced filename
./another spaced filename/x
$ var='spaced filename'
# usually, 'spaced filename' would come from the output of some command and you weren't expecting it
$ rm $var
rm: cannot remove 'spaced': No such file or directory
# oops! I just ran 'rm spaced filename'
$ var='*r*'
$ rm $var
# expands to: 'rm' '-rf' '*r*' 'another spaced filename'
$ find .
.
./another
./spaced filename
./another spaced filename
$ var='another spaced filename'
$ rm -- "$var"
$ find .
.
./another
./spaced filename
Pada portabilitas: Menurut POSIX.1-2008 bagian 2.6.2 , kurung kurawal adalah opsional.
var1=$var
ekspansi memberikan kesalahan?export VAR=$VAR1
. Sedangkan untuk kawat gigi, mereka adalah opsional (periksa paragraf keempat dari bagian yang Anda kutip; ini adalah kasus di semua shell pra-POSIX dan POSIX).${VAR}
dan$VAR
persis sama. Untuk ekspansi variabel biasa, satu-satunya alasan untuk digunakan${VAR}
adalah ketika penguraian sebaliknya akan mengambil terlalu banyak karakter ke dalam nama variabel, seperti dalam${VAR1}_$VAR2
(yang tanpa kawat gigi akan setara dengan${VAR1_}$VAR2
). Ekspansi yang paling menghiasi (${VAR:=default}
,${VAR#prefix}
, ...) membutuhkan kawat gigi.Dalam penugasan variabel, pemisahan bidang (mis. Pemisahan pada spasi putih pada nilai) dan perluasan pathname (yaitu penggumpalan) dimatikan, jadi
VAR=$VAR1
persis sama denganVAR="$VAR1"
, di semua shell POSIX dan di semua sh pre-POSIX yang pernah saya dengar . (POSIX ref: perintah sederhana ). Untuk alasan yang sama,VAR=*
andal disetelVAR
ke string literal*
; tentu sajaVAR=a b
diaturVAR
kea
karena katab
itu terpisah di tempat pertama. Secara umum, tanda kutip ganda tidak diperlukan di mana sintaks shell mengharapkan satu kata, misalnya dalamcase … in
(tetapi tidak dalam pola), tetapi bahkan di sana Anda harus berhati-hati: misalnya POSIX menentukan bahwatarget pengalihan (>$filename
) tidak memerlukan kuotasi dalam skrip, tetapi beberapa shell termasuk bash memang membutuhkan kuotasi ganda bahkan dalam skrip. Lihat Kapan perlu kutip ganda? untuk analisis yang lebih menyeluruh.Anda memang membutuhkan tanda kutip ganda dalam kasus lain, khususnya dalam
export VAR="${VAR1}"
(yang dapat dituliskan secara setaraexport "VAR=${VAR1}"
) dalam banyak shell (POSIX membiarkan case ini terbuka). Kesamaan kasus ini dengan penugasan sederhana, dan sifat daftar kasus yang tersebar di mana Anda tidak memerlukan tanda kutip ganda, itulah sebabnya saya sarankan hanya menggunakan tanda kutip ganda kecuali jika Anda ingin membagi dan menggumpal.sumber
IFS
karakter apa pun karena saya ingin terbiasa. Satu pengecualian adalah saya tidak mengutip nilai ketika melakukan penugasan variabel (kecuali diperlukan, seperti ketika nilai mengandung spasi). Ini membuat penyorotan sintaksis editor lebih berguna ketika ada substitusi perintah sepertiFOO=$(BAR=$(BAZ=blah; printf %s "${BAZ}"); printf %s "${BAR}")
. Alih-alih mewarnai semua warna "string", saya mendapatkan highlight sintaks dari kode bersarang. Ini juga sebabnya saya menghindari backticks.>$file
OK di skrip POSIX, itu tidak di bash bahkan ketika non-interaktif (kecuali kepatuhan POSIX diberlakukan dengan$POSIXLY_CORRECT
atau--posix
...).VAR=$VAR1
, kadang-kadang saya terkejut olehnyalocal VAR=$VAR1
, yang saya ingat bekerja secara berbeda dalam beberapa hal, setidaknya dalam beberapa hal. Tapi atm, saya tidak bisa mereproduksi perbedaan.local VAR=$VAR1
sepertiexport VAR=$VAR1
, itu tergantung pada shell.Kutipan
Pertimbangkan bahwa kutipan ganda digunakan untuk ekspansi variabel, dan kutipan tunggal digunakan untuk penawaran kuat, yaitu, ekspansi sans.
Ekspansi:
Keluaran:
Mungkin bermanfaat untuk menyebutkan bahwa Anda harus menggunakan kutipan sedapat mungkin karena beberapa alasan, di antaranya adalah yang dianggap praktik terbaik, dan untuk keterbacaan. Juga karena Bash kadang-kadang unik dan sering untuk cara yang tampaknya tidak logis atau tidak masuk akal / tidak terduga, dan kutipan mengubah ekspektasi implisit ke eksplisit, yang mengurangi permukaan kesalahan (atau potensi-untuknya).
Dan meskipun sepenuhnya legal untuk tidak mengutip, dan akan berfungsi dalam banyak kasus, fungsionalitas itu disediakan untuk kenyamanan dan mungkin lebih mudah dibawa-bawa. praktik formal sepenuhnya dijamin untuk mencerminkan niat dan harapan adalah mengutip.
Pengganti
Sekarang perhatikan juga bahwa konstruk
"${somevar}"
tersebut digunakan untuk operasi substitusi. Beberapa kasus penggunaan, seperti penggantian, dan array.Penggantian (pengupasan):
Penggantian (replacement):
Array:
Semua ini nyaris tidak menggores permukaan
"${var}"
konstruksi substitusi. Referensi definitif untuk skrip Bash shell adalah referensi online gratis, TLDP The Linux Documentation Projecthttps://www.tldp.org/LDP/abs/html/parameter-substitution.html
sumber
akhir saja:
layak disebut sebagai contoh yang lebih jelas tentang penggunaan ikal
sumber