Apa pentingnya tanda kutip tunggal dan ganda dalam variabel lingkungan?

19

Saya mendefinisikan beberapa variabel lingkungan di profil saya seperti ini:

MY_HOME="/home/my_user"

tetapi variabel tampaknya tidak mengevaluasi kecuali saya menghapus tanda kutip dan sumber kembali file. Saya percaya tanda kutip diperlukan jika akan ada spasi, dan tanda kutip tunggal digunakan jika lolos tidak diinginkan. Dapatkah seseorang mengklarifikasi pentingnya kutipan tunggal dan ganda dalam definisi variabel? Bagaimana dengan kutu depan dan belakang?

2NinerRomeo
sumber

Jawaban:

23

Saya pikir Anda bingung tentang terminologi.

"Variabel lingkungan" hanyalah variabel shell yang diproses oleh setiap anak.

Apa yang Anda lakukan dalam contoh Anda adalah membuat variabel shell. Tidak ada di lingkungan sampai Anda mengekspornya:

MY_HOME="/home/my_user"
export MY_HOME

menempatkan variabel bernama "MY_HOME" di hampir semua shell (csh, tcsh dikecualikan).

Dalam kasus khusus ini, tanda kutip ganda berlebihan. Mereka tidak berpengaruh. Substring grup tanda kutip ganda, tetapi memungkinkan shell apa pun yang Anda gunakan untuk melakukan substitusi variabel. Substring kelompok kutip tunggal dan mencegah substitusi. Karena tugas contoh Anda tidak memiliki variabel di dalamnya, tanda kutip ganda bisa muncul sebagai tanda kutip tunggal.

V='some substrings grouped together'  # assignment
X="Put $V to make a longer string"    # substitution and then assignment
Y=`date`                              # run command, assign its output
Z='Put $V to make a longer string'    # no substition, simple assignment

Tidak ada yang ada di lingkungan sampai Anda mengekspornya.

Bruce Ediger
sumber
18

Variabel shell vs variabel lingkungan

MY_HOME="/home/my_user"menetapkan variabel shell yang disebut MY_HOME. Shell adalah bahasa pemrograman, dan memiliki variabel (juga disebut parameter). Setelah penugasan ini, Anda dapat menggunakan nilai variabel, misalnya dengan echo "$MY_HOME".

Variabel shell adalah konsep shell internal. Ketika instance shell itu berakhir, MY_HOMEdilupakan. Apa yang diketahui oleh setiap program dan ditransmisikan kepada anak-anaknya adalah variabel lingkungan .

Di dalam shell, variabel lingkungan dan variabel shell bekerja dengan cara yang sangat mirip. Apa yang sebenarnya terjadi adalah bahwa semua variabel lingkungan yang diwarisi oleh shell dari induknya menjadi variabel shell. Sebaliknya, variabel shell yang didefinisikan dalam skrip shell akan menjadi variabel lingkungan jika Anda mengekspornya .

export MY_HOME="/home/my_user"

Lebih detail Anda bisa melewatkan membaca pertama

Alasan mengapa variabel shell tidak secara otomatis menjadi variabel lingkungan adalah sebagian karena skrip mungkin secara tidak sengaja menggunakan nama variabel yang bermakna bagi program yang diluncurkannya, dan sebagian hanya historis.

Beberapa shell yang sangat lama exportharus digunakan setiap kali Anda mengubah nama variabel, tetapi semua shell modern melacak penugasan untuk variabel lingkungan, sehingga cuplikan berikut bergema bar:

myvar=foo
export myvar
myvar=bar
env | grep '^myvar='

Juga, beberapa shell yang sangat tua membutuhkan perintah terpisah untuk myvar=foodan export myvar, tetapi semua shell modern mengerti export myvar=foo.

Anda dapat menjalankan set -auntuk membuat semua tugas variabel shell secara otomatis mengekspor variabel, sehingga itu myvar=foosetara dengan export myvar=foojika Anda berlari set -adi shell itu terlebih dahulu.

Saat mengutip

Mengutip sebagian besar ortogonal. Jika nilai yang Anda tetapkan untuk variabel tidak berisi karakter apa pun yang khusus untuk shell, Anda tidak perlu tanda kutip. Jika ada karakter khusus, Anda perlu melindunginya dengan tanda kutip tunggal atau tanda kutip ganda atau garis miring terbalik atau kombinasi keduanya. Ini berlaku untuk myvar=valuesintaks biasa dan exportutilitas.

Ada satu perbedaan antara sintaks penugasan dan exportsintaksis. Shell memperluas hasil substitusi variabel $foolebih lanjut, melakukan pemisahan bidang (kata) dan ekspansi pathname (globbing) . Ini berarti bahwa jika nilainya myvaradalah hello ​ *, maka echo $myvarcetakan hellodiikuti oleh satu spasi diikuti oleh daftar file di direktori saat ini. Ini hampir tidak pernah diinginkan, maka prinsip umum untuk selalu menggunakan tanda kutip ganda sekitar substitusi variabel (kecuali jika Anda tahu bahwa Anda perlu pathname ekspansi atau membelah lapangan): echo "$myvar". Dalam kasus penugasan sederhana, othervar=$myvarsebenarnya dapat diandalkan nilai myvaruntukothervar, karena globbing dan pemisahan kata dihambat dalam penugasan (karena mereka membuat banyak kata, tetapi satu kata diharapkan). Dispensasi ini tidak berlaku untuk export, bagaimanapun. Jadi, jika Anda ingin mengingat aturan sederhana, selalu gunakan tanda kutip ganda di sekitar substitusi variabel.

Gilles 'SANGAT berhenti menjadi jahat'
sumber
Bisakah Anda jelaskan, "Mengutip sebagian besar ortogonal." di bagian "Saat mengutip"? Saya tidak mendapatkan arti ortogonal dalam kalimat itu.
Justice for Monica
1
@DKBose Ini berarti bahwa variabel lingkungan vs shell di satu sisi, dan mengutip di sisi lain, adalah dua masalah terpisah yang tidak ada hubungannya dengan satu sama lain. Arti Wiktionary 4 dan 5.
Gilles 'SO- stop being evil'