bash: Tôi đã phá vỡ [[<]]


14

Tôi đang viết một kịch bản bash và đột nhiên hành vi này bắt đầu:

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

nhưng -lthoạt động tốt:

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

Có phải tôi đã vô tình ghi đè lên <bằng cách nào đó?

đây là kịch bản tôi đã viết để kiểm tra hành vi này:

#!/bin/bash

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

    echo
done

đây là đầu ra:

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

thay đổi <để -lttrong kịch bản cho sản lượng bình thường ( 5 10show lên ví dụ).

Khởi động lại không thay đổi bất cứ điều gì.

Phiên bản bash của tôi là GNU bash, phiên bản 4.3.42 (1) -release (x86_64-pc-linux-gnu). Tôi đang dùng Ubuntu 15.10. Tôi không biết những thông tin khác có liên quan ở đây.


16
Với <thao tác, bạn đang thực hiện so sánh chuỗi, trong khi -lttoán tử là so sánh số, Nếu bạn nhìn vào kết quả bạn đã liệt kê, bạn sẽ nhận ra điều đó. Số 2 nhỏ hơn 10, theo thứ tự abc, ngược lại.
MelBurslan

Câu trả lời:


51

Từ bashtrang người đàn ông.

Khi được sử dụng với [[, toán tử <và> sắp xếp theo từ vựng bằng ngôn ngữ hiện tại.

Từ đầu ra, nó dường như hoạt động như thiết kế.


35
Nói cách khác, hãy đọc trang man trước khi bạn cho rằng bạn đã tìm thấy một lỗi. ;)
tự đại diện

Thật. Có lẽ kịch bản ban đầu tôi đang thực hiện bắt đầu thực sự hoạt động 'chính xác' (như trong thất bại [[$ myvar <13]]) khi tôi nhận thấy hành vi này sau đó. Có bất cứ điều gì tôi nên làm cho câu hỏi này bây giờ? Chúng tôi trên trang web này có thay đổi tiêu đề để bao gồm [giải quyết] hoặc một cái gì đó không? Dù sao tiêu đề nên được thay đổi thành một cái gì đó mô tả hơn?
snail-on-a-Quest

2
Không, đừng thay đổi tiêu đề của câu hỏi. Dấu kiểm bên cạnh câu trả lời này là đủ để cho biết câu hỏi đã được giải quyết.
saiarcot895

14
@Wildcard OP không cho rằng họ tìm thấy lỗi. Họ đề nghị rõ ràng rằng có lẽ họ đã làm gì đó để thay đổi hành vi. Ngay cả tiêu đề giả định càng nhiều!
jpmc26

5

Làm thế nào về:

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

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

Tương tự như lệnh let, cấu trúc ((...)) cho phép mở rộng và đánh giá số học. Ở dạng đơn giản nhất, a = $ ((5 + 3)) sẽ đặt a thành 5 + 3 hoặc 8. Tuy nhiên, cấu trúc dấu ngoặc kép này cũng là một cơ chế cho phép thao tác các biến kiểu C trong Bash, ví dụ , ((var ++)).


2
Bạn đang thiếu điểm của câu hỏi - đó không phải là "làm thế nào tôi có thể so sánh các giá trị đó?" nhưng "tại sao nó lại hành xử theo cách của nó?".
guntbert

7
Điều này đã được trả lời. Nhưng khi anh ta muốn sử dụng một biểu thức số học, có thể đáng để chỉ ra rằng có các cấu trúc tồn tại cho phép bạn sử dụng các biểu thức trong shell.
PaulSmecker

3

Thứ nhất, [[ không phải là POSIX và nên tránh.

Thứ hai, nếu bạn muốn sử dụng <như một phần của bài kiểm tra số học, bạn có thể làm điều này, nhưng với cú pháp khác nhau:

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

Hoặc là:

if expr 2 '<' 13
then
  echo '2 is less than 13'
else
  echo '2 is greater or equal to 13'
fi
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.