Linux betiğinde “okurken…” kullanma


34

Birisi lütfen aşağıdaki kodun nasıl çalıştığını açıklayabilir mi?

echo '1 2 3 4 5 6' | while read a b c
do
  echo $c $b $a
done

Özellikle, bu döngünün çıktısının neden iki ayrı satır 3 4 5 6 2 1yerine 3 2 1ve 6 5 4iki satırda olduğunu bilmek isterim. Aklımı etrafına saracak gibi görünmüyorum ...

Yanıtlar:


41

readstandart girdiden bir satır okur, satırı alanlara böler ve bu alanları verilen değişkenlere atar. Değişkenlerden daha fazla parça varsa, kalan parçalar son değişkene atanır.

Senin durumunda $aatanır 1, $batanır 2ve $ckalan 3 4 5 6.


Teşekkürler Florian! Şimdi mantıklı geliyor ... Bazı nedenlerden dolayı, boşlukların her değişken okumasını sınırlayacağını düşündüm, ama görünüşe göre değil. Yardımlarınız için teşekkür ederim!
— linuxgringo

24

Döngüyü bu şekilde yeniden yazmak, neler olduğunu ortaya çıkarır:

echo '1 2 3 4 5 6' | while read a b c
  do
    echo '(iteration beginning)' a="$a" b="$b" c="$c" '(iteration ending)'
  done

Bu, çıktısı olarak verir:

(iteration beginning) a=1 b=2 c=3 4 5 6 (iteration ending)

İlk önce sadece bir yankı komutunun çalıştırıldığına dikkat edin. Birden fazla kez çalıştırılsaydı, diğer şeylerin yanı sıra, birden fazla basılan (iteration beginning)ve (iteration ending)alt dizileri de görürsünüz .

Bu, whileburada bir döngüye sahip olmanın gerçekten hiçbir şeyi gerçekleştirmediğini söylemek içindir . readYerleşiği boşluk ayrılmış metni okuma 1 her biri belirli bir değişkene. Ekstra giriş belirtilen son değişkenin sonuna eklenir. 2 Böylece değişkenler ave bdeğerleri alır 1ve 2sırasıyla değerleri calır 3 4 5 6.

Döngü koşulu (zaman while read a b c) ikinci kez değerlendirilir, (biz sadece tek bir metin satırı borulu) boru kullanılabilecek başka hiçbir giriş yok yani readkomut değerlendirir YANLıŞ yerine gerçek ve döngü durur (zamankinden yürütme vücut ikinci kez).

1 : Değişken isimleri argüman olarak iletildiğinde , readyerleşik ve teknik olmak gerekirse, girdi okur, IFS boşlukuyla karşılaştığında ayrı "kelimelere" ayırır (ayrıca bu soruya ve bu makaleye bakınız ).

2 : readEk giriş alanlarını belirtilen son değişkene sıkışma davranışı, ilk başta birçok komut dosyası için sezgisel değildir. Florian Diesch'in cevabının dediği gibi , readher zaman bir satırın tamamını okumaya çalışacağını - ve bunun readhem bir döngü hem de bir döngü olmadan kullanılabilir olması amaçlandığını düşündüğünüzde anlamak daha kolay hale gelir .


Eliah, tüm detayları açıklamaya zaman ayırdığınız için teşekkür ederiz. whileBu örnekte normal amacına hizmet etmediğinden şüphelenmiştim , ama sonra readkomut beni susturdu ... Bir şekilde, " read a b cyanlış olmasa da yap echo ..." olarak yorumladım . Gerçekten nasıl çalıştığını açıkladığınız için teşekkürler. Dün bu kodla karşılaştım ve çözene kadar beni
— rahatsız

@linuxgringo Aslında, döngü gövdesi olan her yürütülecek read a b cdoğru olarak değerlendirilir ve döngü durumu ( read a b c) birden fazla kez çalıştırmak etmez. Bit sadece ilk kez doğru olarak değerlendirir . İkinci seferde, borudan okunacak başka girdi yok, bu nedenle dosyanın sonuna rastlanıyor ve yanlışread dönüyor . ( Kabuk komut dosyasında sıfırın doğru ve sıfırın yanlış olduğu anlamına gelmediğine dikkat çekerek, "Çıkış Durumu" nun çıktısının son bölümüne bakın .) Birden fazla girdi satırı için borulama yaparsanız , döngü gövdesi birden çok kez idam edilmek. help readwhile read ...
— Eliah Kagan
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.