[0] neden sonsuz döngüye giriyor?


23

Alttaki döngü için aynı davranışı görüyorum while [ 1 ]. Neden böyle?

while [ 0 ]; do
    echo "hello"
done

Yanıtlar:


33

Kabuktaki tek köşeli parantezler test(ayrı komut veya kabuk yerleşik) ile eşanlamlıdır , yani [ 0 ]aynı anlama gelir test 0. testKarşılaştırma yapmak ve dosya sayfasında okuyabileceğiniz gibi dosyaların özelliklerini test etmek içindir. Bir karşılaştırma, dosya testi veya yapabileceği diğer işlemlerden birine benzeyen bir ifade verilmediğinde, bunun yerine argümanın mevcut olup olmadığını ve boş olmayan bir dize olup olmadığını test eder. Test için gerçekten uygun girdiler de yok 0veya 1bunlar ve boş olmayan karakter dizileri testi basitçe başarılı olur ve while döngüsünüz sonsuza dek döngüye girdi.

Bunun yerine denemek isteyebilirsiniz

while false; do
  echo "hello"
done

muhtemelen değiştirilmesi falseile true. Ya da belki istediğini kullanmaktır (( )):

while (( 0 )); do
  echo "hello"
done

Çoğu dil gibi davranacak olan 0, başarısızlık / yanlış anlamına gelir ve 1 başarı / gerçek anlamına gelir.


1
Re: "Karşılaştırma, dosya testi veya yapabileceği diğer işlemlerden birine benzeyen bir ifade verilmediğinde, sadece başarılı olur": Bunu koymak için iyi bir yol olduğunu sanmıyorum. Sonuçta, [ ](argüman olmadan) ve [ "" ](tek bir boş argümanla) başarılı olamaz .
ruakh

3
@Ruakh'ın açıkladığı gibi, bu ifade yanlıştır: Karşılaştırma, dosya testi veya yapabileceği diğer işlemlerden birine benzeyen bir ifade verilmediğinde, sadece başarılı olur. Argüman boş bir dize değilse testine Herhangi tek argüman (köşeli parantez içindeki herhangi bir tek argüman) DOĞRU kabul edilir ve her ikisi de 0ve 1boş dizeler değildir. Yeni kabuk programcıları genellikle if [ 1=2 ]bunun yerine yazar if [ 1 = 2 ]ve eskinin neden her zaman doğru olduğunu merak ederler. Doğru, çünkü tek bir argüman ve boş bir dize değil.
Ian D. Allen

İyi noktalar, bir düzeltme yaptım.
wingedsubmariner

10

Buradaki 0 ​​değeri sayısal bir sabit değil, karakter dizgisi olarak işlev görür. Bu testlerin tümü, başarılı bir sonlandırma durumu üretme etkisine eşdeğerdir:

[ A ]
[ "XYZ" ]
[ 0 ]

bunlar başarısız bir sonlandırma durumu oluşturur:

[ ]
[ "" ]

mantıksal gerçek olarak değerlendiren, boş olmayan bir argüman var. Bu gibi şeyler yapmanızı sağlar:

if [ $UNDER_NUCLEAR_ATTACK ] ; then
  launch-missiles -a $DRY_RUN  # $DRY_RUN set to "-n" during testing
fi

Değişken UNDER_NUCLEAR_ATTACK, doğru olduğunu belirtmek için boş olmayan bir değere ayarlanır veya yanlış olduğunu belirtmek için ayarlanmamış veya boş.

!Mantığı tersine çevirmek için operatörü uygulayabiliriz :

[ ! a ]  # fails: a is nonblank so true; and not true is false.
[ ! ]    # succeeds: blank is false, not blank is true.

Sayısal bir koşulu değerlendirmek için, sayısal test işleçleri kullanmanız gerekir:

 while [ $A -gt $B ] ; do ...

Eğer Ave Bondalık tamsayılar gibi bakmak, onlar numaraları gibi karşılaştırılır olduğunu dizeleri içerir ve eğer Abüyükse Bdöngü yürütür. Diyelim ki UNDER_NUCLEAR_ATTACKbu, boş ya da kenar olmayan bir dize türü bir boole değil, aslında ya 0(yanlış) ya da başka bir değer (doğru) olan sayısal bir boolean olduğunu varsayalım . Bu durumda, testi şöyle yazarız:

 if [ $UNDER_NUCLEAR_ATTACK -ne 0 ] ; then ...

-1

Bir if / then yap komutu bir komut listesinin çıkış durumunun 0 olup olmadığını test eder (çünkü 0, UNIX kurallarına göre "başarı" anlamına gelir) ve eğer öyleyse, bir veya daha fazla komut yürütür.

Kısacası, sıfır test sonucunu döndürüyorsunuz.

http://www.tldp.org/LDP/abs/html/testconstructs.html


5
Evet, ama düşündüğün nedenden dolayı değil. Eğer [(hariç tek bir tez alır ]sorun olduğu takdirde argüman boş değilse, o durum sıfır çıkar sıfırdan farklı bir değer elbette). Yani, örneğin, [ 1 ]bir çıkış kodu da döndürecektir 0.
Kevin

-1

0 değeri while döngüsü için doğru sayılır, bu nedenle while döngüsü koşulu doğrudur ve bu nedenle sonsuz döngüyü göstermek süreklidir. Eğer 0 ile 1 değiştirirsek doğru olur, koşulu arasına yazdığımız herhangi bir tamsayı olarak doğru

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.