Kutip variabel dalam pernyataan skrip shell “jika”

9

misalnya

if [ "$FOO" = "true" ]; then

vs.

if [ $FOO = "true" ]; then

Apa bedanya? Sepertinya kedua pernyataan itu juga berfungsi.

Ryan
sumber
Di Bash, gunakan tanda kurung ganda dan Anda tidak perlu tanda kutip dan Anda mendapatkan manfaat tambahan .
Dijeda sampai pemberitahuan lebih lanjut.
@ DennisWilliamson Tidak cukup, Anda memang perlu tanda kutip di sisi kanan dari operator kesetaraan dan pencocokan pola (dalam).
Gilles 'SANGAT berhenti menjadi jahat'
@Gilles: Terkadang tidak. Untuk string literal mengandung spasi atau untuk string literal atau variabel yang berisi karakter gumpal yang Anda ingin dipahami secara harfiah , sisi kanan harus dikutip: a='foo bar'; [[ $a == "foo bar" ]]. Namun, variabel yang tidak mengandung karakter gumpal tidak perlu: [[ $a == $a ]]. Ekspansi kata tidak dilakukan di dalam tanda kurung ganda. Dan untuk pencocokan regex, pola di sisi kanan tidak boleh dikutip atau akan diambil sebagai string literal: [[ $a =~ .*oo.*r ]](polanya harus dalam variabel yang tidak dikutip, namun ...
Dijeda hingga pemberitahuan lebih lanjut.
dimasukkan secara harfiah seperti di sini). Untuk pencocokan pola gumpal-gaya, karakter gumpal tidak boleh dikutip, apakah literal atau variabel: [[ $a == foo* ]]. Bisakah Anda memberikan contoh tambahan dari persyaratan untuk mengutip selain contoh string literal saya?
Dijeda sampai pemberitahuan lebih lanjut.

Jawaban:

6

Jika nilai $FOOadalah kata tunggal yang tidak mengandung karakter wildcard \[*?, maka keduanya identik.

Jika $FOOtidak ditetapkan, atau kosong, atau lebih dari satu kata (yaitu, berisi spasi atau $IFS), maka versi yang tidak dikutip adalah kesalahan sintaksis. Jika kebetulan urutan kata-kata yang tepat (seperti 0 -eq 0 -o false), hasilnya bisa sewenang-wenang. Oleh karena itu, praktik yang baik untuk selalu mengutip variabel dalam skrip shell.

Kebetulan, "true"tidak perlu dikutip.

200_sukses
sumber
3

Untuk mengilustrasikan masalah apa yang mungkin ditimbulkannya, berikut beberapa contoh.

Katakanlah kita memiliki dua variabel sebagai berikut:

FOO="some value"
BAR="some value"

Sekarang kita memiliki dua variabel yang memiliki string / nilai yang sama persis. Jika kami melakukan beberapa pernyataan if untuk menguji hasilnya, dalam kasus Anda:

if [ $FOO = "$BAR" ]; then echo "match"; else echo "no match"; fi

Pada titik ini Anda akan dapatkan bash: [: too many arguments. $ FOO yang tidak dikutip memegang sekarang tiga nilai, yaitu '[ , some , value'. [kata kunci uji tidak tahu apa yang harus dieksekusi karena mengharapkan argumen pertama atau kedua untuk menjadi operator.

Ketika kami mengutip "$ FOO", kami secara eksplisit meminta ifuntuk melihat nilai yang tepat di mana tidak ada pemisahan kata.

Contoh lain:

my_file="A random file.txt"
  • melakukan rm $my_fileberarti menghapus 'A' 'acak' 'file.txt' yang menjadikannya tiga file.
  • lakukan rm "$my_file"akan menghapus "file.txt acak" yang membuat satu file.

Semoga saya tidak membingungkan Anda dengan contoh-contoh ini.

Valentin Bajrami
sumber
0

Dalam kasus khusus ini tidak ada perbedaan.

Namun, jika $FOOberisi spasi atau beberapa karakter khusus, Anda akan memiliki masalah.

Dalam hal "$FOO"ini, ia akan menggunakan variabel secara total, untuk membuat kecocokan mengisolasi Anda dari masalah ruang.

Namun, jika Anda menggunakan $FOOdan ada kasus khusus itu akan mempengaruhi pernyataan if.

mdpc
sumber