Alıntılanmış ve alıntılanmamış dize genişletmesi


11
  1. for i in $(xrandr); do echo "$i" ; done
  2. for i in "$(xrandr)"; do echo "$i"; done
  3. for i in "$(xrandr)"; do echo $i; done

Neden 1'in 2'den farklı olduğunu anlıyorum. Ama 3 neden 2'den farklı bir çıktı veriyor? Lütfen çıktıyı da açıklayınız. Tırnak işaretleri yeni satırlarda nasıl çalışır?



Yanıtlar:


19

Sıralanmamış bir değişken (olduğu gibi $var) veya komut ikamesi ( $(cmd)veya `cmd`olduğu gibi ), Bourne benzeri kabuklardaki split + glob operatörüdür.

Yani, içerikleri $IFSözel değişkenin geçerli değerine göre bölünür (varsayılan olarak boşluk, sekme ve yeni satır karakterlerini içerir)

Ve sonra, bu bölünmeden kaynaklanan her kelime dosya adı üretimine ( globbing veya dosya adı genişletmesi olarak da bilinir) tabidir , yani desen olarak kabul edilir ve bu desenle eşleşen dosyalar listesine genişletilir.

Yani for i in $(xrandr), $(xrandr)tırnak içinde olmadığı için, boşluk, sekme ve yeni satır karakterleri dizilerine bölünür. Ve bu bölünmeyle sonuçlanan her kelime eşleşen dosya adları için kontrol edilir (veya herhangi bir dosyayla eşleşmemiş gibi bırakılır) ve forhepsinin üzerine döner.

İçinde for i in "$(xrandr)", komut ikamesi alıntılanırken split + glob operatörünü kullanmıyoruz , bu nedenle döngüde bir değer üzerinde bir geçiş var : çıktısı xrandr( ikame şeritlerini komut veren son satır karakteri olmadan ).

Ancak echo $i, $itekrar alıntı yapılmadığından, içeriği yine $ibölünür ve dosya adı oluşumuna tabidir ve bunlar echokomuta ayrı argümanlar olarak iletilir (ve echoargümanlarını boşluklarla ayrılmış olarak çıkarır).

Böylece alınan ders:

  • sözcük bölme veya dosya adı oluşturma istemiyorsanız , her zaman değişken genişletmeler ve komut ikameleri verin
  • sözcük bölme veya dosya adı oluşturma istiyorsanız , bunları tırnaksız bırakın, ancak $IFSbuna göre ayarlayın ve / veya gerekirse dosya adı oluşturmayı etkinleştirin veya devre dışı bırakın ( set -f, set +f).

Tipik olarak, yukarıdaki örneğinizde, çıktıdaki boş ayrılmış kelime listesi üzerinde döngü yapmak istiyorsanız xrandr, şunları yapmanız gerekir:

  • $IFSboşluklara bölmek için varsayılan değerinde bırakın (veya ayarını kaldırın)
  • Kullanım set -fdevre dışı dosya adı nesil sürece emin olduğun xrandrherhangi çıkarır asla *ya ?ya [(joker dosya nesil modellerinde kullanılan) karakterleri

Ve sonra yalnızca döngü inkısmında split + glob operatörünü kullanın (yalnızca komut ikamesi veya değişken genişlemeyi tırnaksız bırakın) for:

set -f; unset -v IFS
for i in $(xrandr); do whatever with "$i"; done

Çıktının (boş olmayan) satırları arasında geçiş yapmak xrandristiyorsanız $IFS, yeni satır karakterine ayarlamanız gerekir :

IFS='
'

4

Alıntılanan yeni satır, yeni satırdır. Böylece echo "$1"echo'ya tek bir komut satırı argümanı verir ve bu satır yeni satırları doğrudan yazdırır.

Boş bir satırsonu boşluktur. Böylece echo $1yankıya, boşluklarla ayrılmış birbiri ardına basan birçok komut satırı argümanı verir.


Belirtilmemiş bir yeni satır, beyaz alanın, IMO'daki davranışın bir açıklaması olarak gerçekten yararlı olmak için biraz fazla kısa yol olmasıdır.
Stéphane Chazelas
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.