Bash: nhân đôi so với -eq


47

Tôi đang thực hiện so sánh số nguyên trong bash (thử xem người dùng có đang chạy bằng root không) và tôi đã tìm thấy hai cách khác nhau để làm điều đó:

Nhân đôi:

if [ $UID == 0 ]
then
fi

-eq

if [ $UID -eq 0 ]
then
fi

Tôi hiểu rằng không có> = hoặc <= trong bash, chỉ -ge và -le, vậy tại sao lại có ==nếu có -eq?

Có một sự khác biệt trong cách so sánh cả hai bên?


3
Lưu ý rằng không gian bên trong ngoặc là bắt buộc : [ $UID -eq 0 ], không [ $UID -eq 0].
Gilles 'SO- ngừng trở nên xấu xa'

Câu trả lời:


50

==là một bashbí danh cụ thể cho =, thực hiện so sánh chuỗi (từ vựng) thay vì -eqso sánh số. (Nó ngược từ Perl: các toán tử kiểu chữ là số, các toán tử tượng trưng từ vựng.)


Điều đó có nghĩa là nếu cả hai bên là số nguyên, nó sẽ chuyển đổi cả hai bên thành chuỗi và sau đó so sánh chúng?
beatgammit

5
Chính xác hơn là cách khác: mọi thứ đều là một chuỗi, -eqyêu bashcầu diễn giải các chuỗi là số nguyên (tạo ra 0mà không có cảnh báo nếu một chuỗi không phải là số).
geekizard

11
@tjameson Để đưa ra một ví dụ: [ 01 -eq 1 ]nhưng [ 01 != 1 ].
Gilles 'SO- ngừng trở nên xấu xa'

3
Lưu ý rằng mặc dù ==là một [toán tử không chuẩn và không nên được sử dụng, nhưng nó không đặc trưng cho bash . Nó được giới thiệu bởi ksh và cũng được hỗ trợ bởi zsh (mặc dù =cần phải trích dẫn đầu tiên ), yash và [tiện ích GNU (và bất kỳ tiện ích nào được triển khai như tập lệnh ksh trên một số hệ thống).
Stéphane Chazelas

@geekizard Tôi nhận được cảnh báo từ bash v4.3.42 nếu chuỗi của tôi không phải là số: $ if [ "hello" -eq 0 ]; then echo true; fi bash: [: hello: biểu thức số nguyên dự kiến
Andrew Bainbridge

13

Để giải thích về câu trả lời của bollovan ...

Không có >=hoặc <=toán tử so sánh cho chuỗi. Nhưng bạn có thể sử dụng chúng với ((...))lệnh số học để so sánh các số nguyên.

Bạn cũng có thể sử dụng các toán tử so sánh chuỗi khác ( ==, !=, <, >, nhưng không phải =) để so sánh số nguyên nếu bạn sử dụng chúng bên trong ((...)).

Ví dụ

  • Cả hai [[ 01 -eq 1 ]](( 01 == 1 ))làm so sánh số nguyên. Cả hai đều đúng.
  • Cả hai [[ 01 == 1 ]][ 01 = 1 ]làm so sánh chuỗi. Cả hai đều sai.
  • Cả hai (( 01 -eq 1 ))(( 01 = 1 ))sẽ trả lại một lỗi.

Lưu ý: Cú pháp ngoặc kép [[...]]và cú pháp dấu ngoặc kép ((...))không được hỗ trợ bởi tất cả các shell.


1
Lưu ý rằng (ngoại trừ mksh/ zsh(ngoại trừ trong chế độ POSIX (mặc dù đó không phải là tính năng POSIX)), (( 010 == 10 ))sẽ trả về sai vì 010sẽ được coi là số bát phân (8 số thập phân).
Stéphane Chazelas

Lưu ý rằng trong khi hầu hết test/ [triển khai không có >=/ <=nhà khai thác ( yash's [có dù), exprcó nhà khai thác như vậy, mặc dù nó sẽ làm so sánh số học nếu các đối số được công nhận là con số ( expr 01 '>=' 1trả về true, expr X01 '>=' X1false trả).
Stéphane Chazelas

7

Nếu bạn muốn thực hiện so sánh số nguyên, bạn sẽ sử dụng (()) tốt hơn, nơi bạn cũng có thể sử dụng> = vv

Thí dụ:

if (( $UID == 0 )); then
   echo "You are root"
else
   echo "You are not root"
fi

Hoặc (( UID == 0 ))hoặc (( ! UID ))cho vấn đề đó. Lưu ý rằng đó ((...))là không chuẩn (một kshtính năng cũng được hỗ trợ bởi bashzshvới các biến thể).
Stéphane Chazelas
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.