Kabuk değişkeninin genişlemesi ve glob ve ayrılmanın etkisi


18

Bu yazı aslında iki ayrı soru içeriyor, ancak bunları birlikte gruplandırmak biraz daha bağlam verecek. Ben sıkıntıyı yaşayan değişkenler etrafında tırnak bu soruya ama oldukça anlamıyorum değişken genişleme ilk etapta ortalama. İlk sorum:

  1. Unix / linux konuşmada değişken genişleme nedir ?

Sorumun ikinci kısmı aşağıdaki terimlerle ilgilidir:

  1. gıdım bile
  2. Bölünmüş

Yukarıdakiler ne anlama geliyor ve değişken genişlemeyi nasıl etkiliyor? Orijinal sorunun cevabı aşağıdakilerden bahseder:

Tırnakların yokluğunu (liste bağlamlarında) split + glob operatörü olarak düşünün.

Echo $ testi echo glob (bölünmüş ("$ test")) gibi.

Globbing ve yarma kavramına doğrudan hitap eden herhangi bir cevap bulamadım, ancak bu terimleri doğrudan bu son soru gibi diğer soruları cevaplarken kullanır .


Yanıtlar:


15

Değişken genişleme (standart terim parametre genişlemesidir ve bazen değişken ikame olarak da adlandırılır ) temel olarak değişkenin değeriyle değiştirilmesi anlamına gelir. Daha kesin olarak, $VARIABLEyapının (veya ${VARIABLE}veya ${VARIABLE#TEXT}veya diğer yapıların) değişkenin değerinden oluşturulan başka bir metinle değiştirilmesi anlamına gelir . Bu diğer metin, değişkenin genişlemesidir.

Genişleme süreci aşağıdaki gibidir. (Yalnızca genel durumu tartışıyorum, bazı kabuk ayarları ve uzantılar davranışı değiştiriyor.)

  1. Bir dize olan değişkenin değerini al. Değişken tanımlanmamışsa, boş dizeyi kullanın.
  2. Yapı bir dönüşüm içeriyorsa uygulayın. Örneğin, yapı ise ${VARIABLE#TEXT}ve değişkenin değeri ile başlıyorsa , değerin başından TEXTkaldırın TEXT.
  3. Bağlam tek bir sözcük gerektiriyorsa (örneğin çift tırnak içinde veya ödevin sağ tarafında veya burada bulunan bir belgenin içinde), burada durun. Aksi takdirde sonraki adımlarla devam edin.
  4. Bölünmüş boşluk her bir dizinin ayrı kelimelere değer. (Değişken IFS, boşluk dışındaki karakterlere bölünecek şekilde değiştirilebilir.) Sonuç, bu nedenle artık bir dize değil, bir dize listesidir. Değer yalnızca boşluk içeriyorsa bu liste boş olabilir.
  5. Listenin her öğesine bir dosya adı joker karakteri deseni, yani bir glob gibi davranın . Desen bazı dosyalarla eşleşirse, eşleşen dosya adları listesiyle değiştirilir, aksi takdirde yalnız bırakılır.

Örneğin, değişken olduğunu varsayalım fooiçerir a* b* c*ve geçerli dizini dosyalarını içeren bar, bazve paz. Sonra ${foo#??}aşağıdaki gibi genişletilir:

  1. Değişkenin değeri 8 karakterli dizedir a* b* c*.
  2. #??ilk iki karakteri sıyırıp, 6 karakterlik bir dize  b* c*(başlangıç ​​boşluğuna sahip) ile sonuçlanır .
  3. Genişletme liste bağlamındaysa (örneğin, çift tırnak işaretleri veya diğer benzer bağlamlarda değilse), devam edin.
  4. Dizeyi boşlukla ayrılmış kelimelere ayırın ve iki dizeden oluşan bir listeyle sonuçlayın: b*ve c*.
  5. b*Desen olarak yorumlanan dize iki dosyayla eşleşir: barve baz. Dize c*hiçbir dosyayla eşleşmediği için yalnız bırakılır. Sonuç üç dizeleri listesidir: bar, baz, c*.

Örneğin echo ${foo#??}yazdırır bar baz c*(komut echo, bağımsız değişkenlerini arada bir boşlukla birleştirir).

Daha fazla ayrıntı için bkz:


2
Denir o Not parametre genişletme bunun değişkenler (uygulanır çünkü $var) ve parametrelerin diğer türleri gibi $1, $#, $?, $-...
Stéphane Chazelas

12

gıdım bile / bölme

Önce glob / split'i alacağım. @ Stephane'nin bağlandığınız yanıtı bu terimleri genel anlamda kullanmaktır. Bunlar gerçek komutlar ya da bunun gibi bir şey değildir, sadece sahte işlemlerdir.

split("$test")Elementlerin bir "dizisine" içine "$ test" yukarı içeriğini bölmek olacaktır.

Daha glob(...)sonra, *veya aralıklar gibi kabuk globbing karakterleri içeren bu öğelerin herhangi birini genişletmeye özen gösterir [1-2].

Misal

Dize diyelim ki $testaşağıdaki gibidir.

$ test="afile[1-2] afile[3-5]"

Ayrıca içinde bazı dosyalar bulunan bir dizinimiz olduğunu varsayalım.

$ ls -1
afile1
afile2
afile3
afile4
afile5

Şimdi tırnak işaretleri olmadan yankılanmaya çalışırsak, dizimizin boşluklara bölündüğünü ve daha sonra globbing karakterlerinin genişlediğini fark etmelisiniz.

$ echo $test
afile1 afile2 afile3 afile4 afile5

Ancak, değişkeni bir argüman olarak ilettiğimizde değişkeni alıntılarsak echo, orijinal değişmez dizgeyi alırdık.

$ echo "$test"
afile[1-2] afile[3-5]

değişken genişleme

Değişken genişleme terimi, kabuğun temel işlemlerinin bir parçası olarak gerçekleştirdiği temel işlemi kapsamaktadır. Kabuk girdiyi ayrıştırmaktan ve sözdizimsel olarak doğru kabul edildikten sonra bu girdiyi yürütmekten sorumludur.

Önceki örneğimizde. Değişken alıntılanmamış $testolarak sunulduğunda echo, kabuğa devam etmesini ve bu argümanları bölmesini ve sonra onları yutmasını söylüyorduk.

Alıntı yapıldığında, aslında çift tırnak ile sarılmış olan değişken (ler) ile bu özelliği devre dışı bırakıyorduk.

Misal

İşte bazı globbing ve yarma örnekleri.

glob / bölme otomatik olarak gerçekleşir

$ echo file{1..3}
file1 file2 file3

$ echo file{1..3} dir{a..b}
file1 file2 file3 dira dirb

$ echo dir{z..w} file{A..D}
dirz diry dirx dirw fileA fileB fileC fileD

$ echo dir{z..w} file{A..B} fileC
dirz diry dirx dirw fileA fileB fileC

glob / split çift tırnak ile devre dışı bırakıldı

$ echo "dir{z..w} file{A..B} fileC"
dir{z..w} file{A..B} fileC

$ echo "dir{z..w} file{A..B}"
dir{z..w} file{A..B}

Aralıkları da ters sırada çalıştı bilmiyordum.
Joe
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.