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 for
hepsinin ü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
, $i
tekrar alıntı yapılmadığından, içeriği yine $i
bölünür ve dosya adı oluşumuna tabidir ve bunlar echo
komuta ayrı argümanlar olarak iletilir (ve echo
argü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
$IFS
buna 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:
$IFS
boşluklara bölmek için varsayılan değerinde bırakın (veya ayarını kaldırın)
- Kullanım
set -f
devre dışı dosya adı nesil sürece emin olduğun xrandr
herhangi çıkarır asla *
ya ?
ya [
(joker dosya nesil modellerinde kullanılan) karakterleri
Ve sonra yalnızca döngü in
kı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 xrandr
istiyorsanız $IFS
, yeni satır karakterine ayarlamanız gerekir :
IFS='
'