Dalam skrip shell, jika saya mendefinisikan variabel seperti FOO=25
, apakah ada perbedaan antara referensi sebagai $FOO$
dan ${FOO}$
?
Dalam skrip shell, jika saya mendefinisikan variabel seperti FOO=25
, apakah ada perbedaan antara referensi sebagai $FOO$
dan ${FOO}$
?
Jawaban:
Dalam kebanyakan situasi baik $var
dan ${var}
adalah sama. (Perhatikan bahwa Anda tidak boleh menggunakan $
di akhir!)
Salah satu contoh di mana Anda perlu kurung kurawal adalah ketika Anda harus meletakkan variabel dalam string yang berkelanjutan.
Contoh:
var=hel
echo ${var}lo
akan menampilkan hello
.
Untuk menjawab pertanyaan utama Anda, ${foo}
disebut "ekspansi parameter" . Tepatnya, $
parameter itu sendiri memulai ekspansi parameter, { }
sebenarnya opsional sesuai dengan spesifikasi POSIX , tetapi dapat berguna untuk menunjukkan akhir nama variabel:
$ foo="bar"
$ echo $fooBaz ## fails, no variable named $fooBaz exists
$ echo ${foo}Baz ## works, $foo is expanded and the string Baz is appended
barBaz
Pada dasarnya, $foo
dan ${foo}
identik. Terlepas dari kasus-kasus seperti di atas atau ketika Anda melakukan manipulasi string , mereka sepenuhnya setara.
Namun, Anda sebaiknya tidak menggunakan keduanya. Aturan praktisnya adalah bahwa, dengan sedikit pengecualian, Anda harus selalu menggunakan "$foo"
atau "${foo}"
dan tidak pernah $foo
atau ${foo}
. Anda harus selalu mengutip variabel Anda untuk menghindari meminta operator split + glob (lebih lanjut tentang itu nanti). Anda tentu tidak mau $foo$
. Final $
tidak relevan:
$ foo="bar"
$ echo "$foo$"
bar$
Jadi, sementara variabel yang tidak dikutip kadang-kadang OK:
$ echo $foo
bar
Mereka biasanya tidak dan harus benar-benar dihindari:
$ if [ -n $foo ]; then echo empty; else echo "not empty"; fi ## fails
empty
$ if [ -n "$foo" ]; then echo empty; else echo "not empty"; fi ## works
not empty
Perhatikan bahwa kurung juga tidak membantu di sini:
$ if [ -n ${foo} ]; then echo empty; else echo "not empty"; fi ## fails
empty
$ if [ -n "${foo}" ]; then echo empty; else echo "not empty"; fi ## works
not empty
Saat Anda menggunakan $foo
atau ${foo}
, shell akan membagi nilai yang disimpan dalam variabel di spasi putih (ini dapat diubah dengan mengatur IFS
variabel ke sesuatu yang lain) menjadi daftar dan kemudian, setiap elemen daftar diperlakukan sebagai pola gumpalan dan diperluas ke file atau direktori yang cocok. Ini dikenal sebagai operator split + glob . Untuk mengilustrasikannya, pertimbangkan direktori dengan dua file:
$ ls -l
-rw-r--r-- 1 terdon terdon 0 Oct 9 18:16 file1
-rw-r--r-- 1 terdon terdon 0 Oct 9 18:16 file2
Sekarang, mari kita tetapkan variabel ke foo *
:
$ foo="foo *"
Apa yang terjadi jika kami mencoba memeriksa apakah ada file dengan nama itu?
$ if [ -e $foo ]; then echo "file exists"; else echo "no such file"; fi
file exists
Variabel dipecah menjadi foo
dan *
dan, karena *
wildcard yang cocok dengan string apa pun, shell memberitahu Anda bahwa file bernama foo *
exxists. Namun, jika kami mengutipnya dengan benar, ini tidak terjadi:
$ if [ -e "$foo" ]; then echo "file exists"; else echo "no such file"; fi
no such file
Itu adalah contoh sepele untuk menggambarkan hal tersebut. Bayangkan jika saya telah menggunakan rm
bukannya echo
sekalipun.
Jadi, aturan pertama: selalu kutip variabel Anda. Anda dapat menggunakan salah satu "$foo"
atau "${foo}"
tetapi mengutipnya dengan cara apa pun. Untuk detail lebih lanjut tentang penggunaan variabel dengan aman, lihat posting ini:
$ var="foo *"
menjadi $ foo="foo *"
? Anda tidak menggunakannya di var
mana pun.
$
pada akhirnya! Ini akan diperlakukan sebagai karakter normal dan bukan sebagai bagian dari nama variabel.