2013-12-08 25 views
40

Ai đó có thể giải thích sự khác biệt giữa -eq== trong tập lệnh bash không?Bash Nhà điều hành bình đẳng (==, -eq)

Có sự khác biệt nào sau đây không?

[ $a -eq $b ][ $a == $b ]

là nó chỉ đơn giản rằng == chỉ được sử dụng khi các biến chứa số?

Trả lời

54

Đó là cách khác xung quanh: == là để so sánh chuỗi, -eq là dành cho số. -eq nằm trong cùng một họ với tên là -lt, -le, -gt, -ge-ne, nếu điều đó giúp bạn nhớ cái nào.

$ [ a == a ]; echo $? 
0 
$ [ a -eq a ]; echo $? 
-bash: [: a: integer expression expected 
2 

== là bash-ism. Biểu mẫu POSIX là =. Nếu tính di động đối với các shell không bash là quan trọng, hãy sử dụng =.

13

== là bí danh bash cụ thể cho = và nó thực hiện so sánh chuỗi (từ điển) thay vì so sánh bằng số. eq là một so sánh số của khóa học.

Cuối cùng, tôi thường thích sử dụng các hình thức if [ "$a" == "$b" ]

+6

Sử dụng '== 'ở đây là hình thức xấu, như chỉ' =' được xác định bởi POSIX . –

+2

Nếu bạn thực sự nhấn mạnh để sử dụng '==' thì đặt nó vào giữa '[[' và ']]'. (Và đảm bảo rằng dòng đầu tiên của tập lệnh chỉ định sử dụng '/ bin/bash'.) – holgero

7

Nó phụ thuộc vào Test Construct xung quanh các nhà điều hành. lựa chọn của bạn là dấu ngoặc kép, dấu ngoặc kép, dấu ngoặc đơn, hoặc test

Nếu bạn sử dụng ((...)), bạn đang thử nghiệm công bằng số học với == như trong C:

$ ((1==1)); echo $? 
0 
$ ((1==2)); echo $? 
1 

(Lưu ý: 0 nghĩa true trong Unix ý nghĩa và không phải là một thử nghiệm không thành công)

Sử dụng -eq bên trong dấu ngoặc kép là lỗi cú pháp.

Nếu bạn đang sử dụng [...] (hoặc dây đeo duy nhất) hoặc [[...]] (hoặc dây đeo kép), hoặc test bạn có thể sử dụng một trong -eq, -ne, -lt, -le, -gt, hoặc -ge như một arithmetic comparison .

$ [ 1 -eq 1 ]; echo $? 
0 
$ [ 1 -eq 2 ]; echo $? 
1 
$ test 1 -eq 1; echo $? 
0 

Các == bên trong đơn hoặc kép niềng răng (hoặc test lệnh) là một trong những string comparison operators:

$ [[ "abc" == "abc" ]]; echo $? 
0 
$ [[ "abc" == "ABC" ]]; echo $? 
1 

Như một nhà điều hành chuỗi, = tương đương với == và lưu ý các khoảng trắng xung quanh = hoặc == yêu cầu của nó.

Trong khi bạn có thể làm [[ 1 == 1 ]] hoặc [[ $((1+1)) == 2 ]] nó đang thử nghiệm bình đẳng chuỗi - không phải là bình đẳng số học.

Vì vậy -eq sản xuất kết quả lẽ Dự kiến ​​giá trị số nguyên của 1+1 bằng 2 mặc dù RH là một chuỗi và có một không gian dấu:

$ [[ $((1+1)) -eq "2 " ]]; echo $? 
0 

Trong khi một chuỗi so sánh của cùng một chọn không gian theo sau và do đó so sánh chuỗi không thành công:

$ [[ $((1+1)) == "2 " ]]; echo $? 
1 

Và so sánh chuỗi sai lầm có thể tạo ra hoàn thành e sai câu trả lời. '10' là theo từ điển nhỏ hơn '2', do đó, so sánh chuỗi trả về true hoặc 0. Vì vậy, nhiều người đang bị cắn bởi lỗi này:

$ [[ 10 < 2 ]]; echo $? 
0 

vs các thử nghiệm chính xác cho 10 là số học ít hơn 2:

$ [[ 10 -lt 2 ]]; echo $? 
1 

Trong ý kiến, có một câu hỏi của kỹ thuật lý do sử dụng số nguyên -eq trên chuỗi trả về Đúng cho các chuỗi không giống nhau:

$ [[ "yes" -eq "no" ]]; echo $? 
0 

Lý do là Bash là untyped. Các -eq làm cho chuỗi để được hiểu là số nguyên nếu có thể bao gồm chuyển đổi cơ sở:

$ [[ "0x10" -eq 16 ]]; echo $? 
0 
$ [[ "010" -eq 8 ]]; echo $? 
0 
$ [[ "100" -eq 100 ]]; echo $? 
0 

0 nếu Bash nghĩ nó chỉ là một chuỗi:

$ [[ "yes" -eq 0 ]]; echo $? 
0 
$ [[ "yes" -eq 1 ]]; echo $? 
1 

Vì vậy [[ "yes" -eq "no" ]] tương đương với [[ 0 -eq 0 ]]

Lưu ý cuối cùng: Nhiều phần mở rộng cụ thể của Bash đối với Cấu trúc thử nghiệm không phải là POSIX và do đó sẽ không thành công trong các trình bao khác. Các trình bao khác thường không hỗ trợ [[...]]((...)) hoặc ==.

+0

Tôi tò mò về * lý do kỹ thuật * cho '[[" yes "-eq" no "]]' trả về True. Làm thế nào để bash ép buộc các chuỗi này thành các giá trị số nguyên có thể được so sánh? ;-) – odony

+1

Biến Bash là [untyped] (http://www.tldp.org/LDP/abs/html/untyped.html) để '[[" yes "-eq" no "]]' tương đương với ' [["có" -eq 0]] 'hoặc' [["có" -eq "any_noninteger_string"]] '- Tất cả đều đúng. '-eq' so sánh số nguyên. Chữ "" có "' được hiểu là số nguyên '0'; so sánh là True nếu số nguyên khác là '0' hoặc kết quả chuỗi là' 0'. – dawg

+0

@odony: Xem cập nhật – dawg

0

Guys: Một số câu trả lời hiển thị các ví dụ nguy hiểm. Ví dụ của OP [ $a == $b ] thay thế biến số không được sử dụng cụ thể (kể từ ngày chỉnh sửa tháng 10 năm17). Đối với [...] an toàn cho chuỗi bình đẳng.

Nhưng nếu bạn định liệt kê các lựa chọn thay thế như [[...]], bạn cũng phải thông báo rằng phía bên tay phải phải được trích dẫn. Nếu không được trích dẫn, đó là một mẫu phù hợp! (Từ trang bash man: "Bất kỳ phần nào của mẫu có thể được trích dẫn để buộc nó được khớp như một chuỗi.").

đây trong bash, hai báo cáo năng suất "có" là mô hình phù hợp, ba người kia là bình đẳng chuỗi:

$ rht="A*" 
$ lft="AB" 
$ [ $lft = $rht ] && echo yes 
$ [ $lft == $rht ] && echo yes 
$ [[ $lft = $rht ]] && echo yes 
yes 
$ [[ $lft == $rht ]] && echo yes 
yes 
$ [[ $lft == "$rht" ]] && echo yes 
$ 
Các vấn đề liên quan