bash: Saya bangkrut [[<]]


14

Saya sedang menulis skrip bash dan tiba-tiba perilaku ini dimulai:

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

tapi -ltbekerja dengan baik:

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

Apakah saya <entah bagaimana secara tidak sengaja menimpa ?

berikut ini skrip yang saya tulis untuk menguji perilaku ini:

#!/bin/bash

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

    echo
done

di sini adalah output:

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

mengubah <ke -ltdalam skrip memberikan output normal ( 5 10muncul misalnya).

Mem-boot ulang tidak mengubah apa pun.

Versi bash saya adalah GNU bash, versi 4.3.42 (1) -release (x86_64-pc-linux-gnu). Saya di Ubuntu 15.10. Saya tidak tahu informasi apa yang relevan di sini.


16
dengan <operasi, Anda membuat perbandingan string, sedangkan -ltoperator perbandingan numerik, Jika Anda melihat hasil yang telah Anda daftarkan, Anda akan menyadarinya. Secara numerik 2 kurang dari 10, menurut abjad, sebaliknya.
MelBurslan

Jawaban:


51

Dari bashhalaman manual.

Saat digunakan dengan [[, operator <dan> mengurutkan secara leksikografis menggunakan lokal saat ini.

Dari output, tampaknya berfungsi seperti yang dirancang.


35
Dengan kata lain, baca halaman manual sebelum Anda menganggap Anda telah menemukan bug. ;)
Wildcard

Benar. Mungkin skrip yang semula saya kerjakan mulai benar-benar berfungsi 'dengan benar' (seperti pada kegagalan [[$ myvar <13]]) ketika saya memperhatikan perilaku ini. Apakah ada yang harus saya lakukan untuk pertanyaan ini sekarang? Apakah kita di situs ini mengubah judul untuk memasukkan [diselesaikan] atau sesuatu? Haruskah judul diubah pula menjadi sesuatu yang lebih deskriptif?
bekicot

2
Tidak, jangan ubah judul pertanyaan. Tanda centang di sebelah jawaban ini cukup untuk menunjukkan bahwa pertanyaan telah diselesaikan.
saiarcot895

14
@ Kartu Memori OP tidak menganggap mereka menemukan bug. Mereka secara eksplisit menyarankan bahwa mungkin mereka telah melakukan sesuatu untuk mengubah perilaku. Bahkan judulnya juga banyak!
jpmc26

5

Bagaimana tentang:

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

Menurut http://www.tldp.org/LDP/abs/html/dblparens.html

Mirip dengan perintah let, konstruk ((...)) memungkinkan ekspansi dan evaluasi aritmatika. Dalam bentuknya yang paling sederhana, a = $ ((5 + 3)) akan menetapkan menjadi 5 + 3, atau 8. Namun, konstruk tanda kurung ganda ini juga merupakan mekanisme untuk memungkinkan manipulasi gaya-C dari variabel dalam Bash, misalnya , ((var ++)).


2
Anda melewatkan inti pertanyaan - bukan "bagaimana saya bisa membandingkan nilai-nilai itu?" tetapi "mengapa itu berperilaku seperti itu?".
guntbert

7
Ini sudah dijawab. Tetapi karena dia ingin menggunakan ekspresi aritmatika, mungkin ada baiknya menunjukkan bahwa ada konstruksi yang memungkinkan Anda untuk menggunakan yang ada di shell.
PaulSmecker

3

Pertama, [[ bukan POSIX dan harus dihindari.

Kedua, jika Anda ingin menggunakan <sebagai bagian dari tes aritmatika Anda dapat melakukan ini, tetapi dengan sintaks yang berbeda:

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

Atau:

if expr 2 '<' 13
then
  echo '2 is less than 13'
else
  echo '2 is greater or equal to 13'
fi
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.