bash: Kırdım [[<]]


14

Bir bash senaryosu yazıyordum ve aniden bu davranış başladı:

[[ 1 < 2 ]]; echo $?  # outputs 0
[[ 2 < 13 ]]; echo $? # outputs 1

ama -ltsağlıklı çalışır:

[[ 1 -lt 2 ]]; echo $?  # outputs 0
[[ 2 -lt 13 ]]; echo $? # outputs 0

bir <şekilde yanlışlıkla üzerine yazdım mı?

İşte bu davranışı test etmek için yazdığım bir komut dosyası:

#!/bin/bash

for a in {1..5}
do
    for b in {1..20}
    do
        [[ $a < $b ]] && echo $a $b
    done

    echo
done

İşte çıktı:

1 2
1 3
1 4
1 5
1 6
1 7
1 8
1 9
1 10
1 11
1 12
1 13
1 14
1 15
1 16
1 17
1 18
1 19
1 20

2 3
2 4
2 5
2 6
2 7
2 8
2 9
2 20

3 4
3 5
3 6
3 7
3 8
3 9

4 5
4 6
4 7
4 8
4 9

5 6
5 7
5 8
5 9

Değişen <için -ltkomut normal çıkış verir ( 5 10gösterir örneğin kadar).

Yeniden başlatma hiçbir şeyi değiştirmedi.

Benim bash versiyonum GNU bash, versiyon 4.3.42 (1) -çalışma (x86_64-pc-linux-gnu). Ubuntu 15.10 kullanıyorum. Burada başka hangi bilgilerin alakalı olduğunu bilmiyorum.


16
ile <operasyon, sen, oysa bir dize karşılaştırma yapıyoruz -ltoperatör sayısal karşılaştırma Listelediğiniz sonuçlarına bakacak olursak, bunu anlayacaktır. Sayısal olarak 2, alfabetik olarak, tam tersi 10'dan küçüktür.
MelBurslan

Yanıtlar:


51

Gönderen bashadam sayfası.

[[İle kullanıldığında, <ve> operatörleri geçerli yerel ayarı kullanarak sözlükbilimsel olarak sıralar.

Çıktıdan, tasarlandığı gibi çalışıyor gibi görünüyor.


35
Başka bir deyişle, bir hata bulduğunuzu varsaymadan önce kılavuz sayfasını okuyun . ;)
Joker karakter

Doğru. Ben aslında bu davranış fark o zaman aslında üzerinde çalıştığım script aslında 'doğru' (başarısız [[$ myvar <13]] gibi) çalışmaya başladı. Bu soruya şimdi yapmam gereken bir şey var mı? Bu sitedeki başlığı [çözüldü] veya başka bir şey içerecek şekilde değiştiriyor muyuz? Başlık yine de daha açıklayıcı bir şeye değiştirilmeli mi?
görevde salyangoz

2
Hayır, sorunun başlığını değiştirmeyin. Bu cevabın yanındaki onay işareti sorunun çözüldüğünü belirtmek için yeterlidir.
saiarcot895

14
@Wildcard OP bir hata bulduğunu varsaymaz. Açıkça, belki de davranışı değiştirmek için bir şeyler yaptıklarını ileri sürerler. Hatta başlık bile kabul edilir!
jpmc26

5

Nasıl olur:

for a in {1..5}; 
do     
  for b in {1..20};     
  do         
    (( $a < $b )) && echo $a $b
  done      
  echo
done

Http://www.tldp.org/LDP/abs/html/dblparens.html adresine göre

Let komutuna benzer şekilde, ((...)) yapısı aritmetik genişleme ve değerlendirmeye izin verir. En basit haliyle, a = $ ((5 + 3)), 5 + 3 veya 8'e ayarlayacaktır. Ancak, bu çift parantez yapısı aynı zamanda Bash'teki değişkenlerin C stili manipülasyonuna izin veren bir mekanizmadır, örneğin , ((var ++)).


2
Sorunun noktasını kaçırıyorsunuz - "bu değerleri nasıl karşılaştırabilirim?" Değil. ama "neden olduğu gibi davranıyor?".
guntbert

7
Bu zaten cevaplandı. Ancak aritmetik bir ifade kullanmak istediği için, bunları kabukta kullanmanıza izin veren yapılar olduğunu belirtmeye değer olabilir.
PaulSmecker

3

İlk olarak [[ POSIX değildir ve bundan kaçınılmalıdır.

İkincisi, <aritmetik bir testin parçası olarak kullanmak istiyorsanız, bunu yapabilirsiniz, ancak farklı sözdizimi ile:

if [ $((2 < 13)) = 1 ]
then
  echo '2 is less than 13'
else
  echo '2 is greater or equal to 13'
fi

Veya:

if expr 2 '<' 13
then
  echo '2 is less than 13'
else
  echo '2 is greater or equal to 13'
fi
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.