Kabuk betiğindeki değişkenlere başvuruda bulunma


10

Bir kabuk betiğinde, gibi bir değişken tanımlarsam FOO=25, $FOO$ve olarak başvurmak arasında bir fark var ${FOO}$mıdır?


2
$Sonunda kullanmamalısınız ! Değişken adının bir parçası olarak değil, normal karakter olarak değerlendirilir.
Bayt Komutanı

Yanıtlar:


16

Çoğu durumda, hem $varve ${var}aynıdır. ( $Sonunda a kullanmamalısınız !)

Kıvırcık parantezlere ihtiyacınız olan bir örnek, sürekli bir dizeye bir değişken koymanız gerektiğidir.

Misal:

var=hel
echo ${var}lo

çıktı hello.


11

Ana sorunuza cevap vermek için "parametre genişletme"${foo} denir . Kesin olmak gerekirse, kendisi parametre genişletmeye başlar , POSIX belirtimine göre aslında isteğe bağlıdır , ancak değişkenin adının sonunu belirtmek için yararlı olabilir:${ }

$ foo="bar"
$ echo $fooBaz   ## fails, no variable named $fooBaz exists

$ echo ${foo}Baz ## works, $foo is expanded and the string Baz is appended
barBaz

Temel olarak $foove ${foo}aynıdır. Yukarıdaki gibi durumlar dışında veya dize manipülasyonu yaparken , bunlar tamamen eşdeğerdir.

Ancak, hiçbirini gerçekten kullanmamalısınız. Temel kural çok az istisna dışında, sen gerektiğini, yani her zaman kullanabilir "$foo"veya "${foo}"ve asla $fooya ${foo}. Split + glob operatörünü çağırmaktan kaçınmak için değişkenlerinizi her zaman alıntılamalısınız (bundan sonra daha fazlası). Kesinlikle istemiyorsun $foo$. Final $ilgisiz:

$ foo="bar"
$ echo "$foo$"
bar$

Dolayısıyla, sıralanmamış değişkenler bazen uygun olsa da:

$ echo $foo
bar

Genellikle kaçınılmaz ve gerçekten kaçınılmalıdır:

$ 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

Parantezlerin burada da yardımcı olmadığını unutmayın:

$ 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

$fooVeya kullandığınızda ${foo}, kabuk boşlukta değişkene kaydedilen değeri böler (bu, IFSdeğişkeni başka bir şeye ayarlayarak değiştirilebilir ) ve daha sonra listenin her öğesi bir glob deseni olarak ele alınır ve eşleşen dosyalar veya dizinler. Bu split + glob operatörü olarak bilinir . Örneklemek için iki dosya içeren bir dizini göz önünde bulundurun:

$ 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

Şimdi bir değişken belirleyelim foo *:

$ foo="foo *"

Bu ada sahip bir dosyanın var olup olmadığını kontrol etmeye çalışırsak ne olur?

$ if [ -e $foo ]; then echo "file exists"; else echo "no such file"; fi
file exists

Değişken ayrıldı foove *yana ve *herhangi bir dize eşleşen bir joker olduğunu, kabuk bir dosya adı verilen anlatır foo *exxists. Ancak, doğru bir şekilde alıntı yaparsak, bu olmaz:

$ if [ -e "$foo" ]; then echo "file exists"; else echo "no such file"; fi
no such file

Bu konuyu açıklamak için önemsiz bir örnekti. Kullanmış olsaydı düşünün rmyerine echogerçi.

Yani, ilk kural: her zaman değişkenlerinizi belirtin. İkisinden birini kullanabilirsiniz "$foo"veya "${foo}"her iki şekilde de alıntı yapabilirsiniz . Değişkenleri güvenli bir şekilde kullanma hakkında daha fazla bilgi için şu yayınlara göz atın:


Ben Senin o mükemmel cevabı düzenlemek istemediğini, ancak olmamalıdır $ var="foo *"olmak $ foo="foo *"? Hiçbir varyerde kullanmıyorsunuz .
Joe

@Joe oh, keder! Evet, elbette olmalı, işaret ettiğiniz için teşekkürler. Bu arada, bir düzenleme önererek bu tür hataları düzeltmekten çekinmeyin. Böyle bir şey saçma hatalardan kaçınmak için bu tür şeyler çok teşvik edilir.
terdon
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.