2013-04-07 26 views
13

Tôi đã thử so sánh xem hai số trong Bash có bằng nhau không (và in một thông báo nếu chúng bằng nhau), nhưng tôi nhận được một số thông báo lỗi lạ cho chương trình đơn giản này :Kiểm tra xem một số có bằng một số khác trong bash

#!/bin/bash 

fun2(){ 
    $x = 3 
    //#prog.sh: line 4: =: command not found 
    if [x == 3] 
     then 
    //#prog.sh: line 6: [x: command not found 
      echo "It's 3!" 
    fi 
} 
fun2 

Lỗi tương ứng được hiển thị bên dưới các dòng gây ra lỗi đó.

+0

Tôi hy vọng sự thiếu hiểu biết của tôi sẽ được tha thứ: Tôi tương đối mới để lập trình bash, và cú pháp của nó không giống như bất kỳ ngôn ngữ lập trình nào khác mà tôi đã thấy. –

Trả lời

24

Nó phải là:

if [ $x -eq 3 ]; then ..... 

giải thích:

Để so sánh số nguyên bạn phải sử dụng những nhà khai thác (sao chép từ kiểm tra người đàn ông):

INTEGER1 -eq INTEGER2 
      INTEGER1 is equal to INTEGER2 

    INTEGER1 -ge INTEGER2 
      INTEGER1 is greater than or equal to INTEGER2 

    INTEGER1 -gt INTEGER2 
      INTEGER1 is greater than INTEGER2 

    INTEGER1 -le INTEGER2 
      INTEGER1 is less than or equal to INTEGER2 

    INTEGER1 -lt INTEGER2 
      INTEGER1 is less than INTEGER2 

    INTEGER1 -ne INTEGER2 
      INTEGER1 is not equal to INTEGER2 

khai thác == và! = chỉ để so sánh chuỗi.

để biết thông tin: "[" lệnh là bí danh cho lệnh "kiểm tra" hệ thống.

+0

+1 để có câu trả lời đúng. –

0
  • các không gian là bắt buộc trong biểu thức [ ], vì vậy

    if [ $x == 3 ]; then

  • bạn cần một sigill trên biến trong [ ] kiểm tra

2

Đối với các thông báo lỗi đầu tiên, loại bỏ các ký hiệu đô la $ và không có khoảng trống được cho phép xung quanh e qual ký =

x=3 

Đối với các thông báo lỗi thứ hai, chèn một không gian và một ký hiệu đô la $ trước x và một không gian sau khi 3

if [ $x -eq 3 ] 

Như @loentar một cách chính xác chỉ ra, nó phải là -eq và không phải = cũng không phải ==.

1

Tạo tập lệnh shell không thực sự là ngôn ngữ đầy đủ và nó phụ thuộc nhiều vào các lệnh bên ngoài khác để hoạt động.

Biến số sử dụng sigil có nghĩa là $ trước mặt chúng. Rất nhiều ngôn ngữ kịch bản lệnh shell sử dụng các biến sigils để giúp phân biệt giữa một chuỗi và một biến.

Ví dụ:

foo=foo_value 
echo foo foo $foo foo 

Sẽ in:

foo foo foo_value foo 

Lưu ý rằng dấu ngoặc kép là không cần thiết cho việc vang tuyên bố cho các chuỗi.Cửa sổ hàng loạt vỏ rất giống:

set foo = foo_value 
echo foo foo %foo% foo 

Như bạn có thể thấy, sigil được sử dụng khi biến là giả sử để được mở rộng, nhưng không phải khi bạn định nghĩa nó. Đó là bởi vì vỏ Unix là các vỏ thông minh. Họ munge dòng lệnh trước khi nó được thực thi. Vỏ sẽ thay thế các biến môi trường trước thực hiện:

foo=bar 
$foo="whose value is this" #Note the dollar sign! 
echo The value of foo is $foo 
echo The value of bar is $bar 

này sẽ in ra:

The value of foo is foo 
The value of bar is whose value is this 

Nếu bạn sử dụng lệnh set -xv, bạn sẽ thấy rằng $foo="whose value is this" được mở rộng để bar=whose value is this" trước khi nó được thực hiện.

Trong vỏ kiểu Bourne như Kornshell và BASH, tuyên bố if không phải là ý của bạn. Lệnh if thực thi câu lệnh và sẽ chọn mệnh đề nếu khoản nếu lệnh đó trả về giá trị bằng không. Ví dụ:

cat "foo" > my_file  #Create a one line file with the string foo in it. 
if grep -q "foo" my_file #grep command will return a zero exit code if it finds foo 
then 
    echo "The string 'foo' is in file my_file" 
fi 

Lưu ý rằng nếu mệnh đề không phải là một câu lệnh logic. Đó là một lệnh thực tế được thực hiện.

Một nơi nào đó sớm trong phát triển Unix, lệnh test đã được tạo. Bạn có thể thực hiện thử nghiệm người đàn ông và xem cách sử dụng nó.

Lệnh test cho phép bạn làm điều này:

foo=3 
bar=3 
if test foo -eq bar 
then 
    echo "foo and bar are equal" 
else 
    echo "foo and bar are not equal" 
fi 

Nếu bạn làm điều này:

$ ls -li /bin/test /bin/[ 

Bạn sẽ thấy rằng một lệnh gọi [ thực sự tồn tại, và là một liên kết cứng đến test lệnh. Điều này đã được tạo ra để làm cho một tuyên bố if trông giống như một câu lệnh if bạn sẽ thấy trong các ngôn ngữ lập trình thường xuyên:

foo=3 
bar=3 
if [ foo -eq bar ] 
then 
    echo "foo and bar are equal" 
else 
    echo "foo and bar are not equal" 
fi 

chính xác kịch bản tương tự như trên, nhưng với [ thay vì test.

Điều này giải thích tại sao bạn cần dấu gạch ngang trong nhiều thử nghiệm (đó là tham số cho lệnh test và tham số bắt đầu bằng dấu gạch ngang!). Nó cũng giải thích tại sao bạn cần khoảng trống xung quanh []. Đây là các lệnh Unix thực tế và các lệnh Unix phải có khoảng trắng xung quanh chúng, vì vậy trình bao có thể xử lý chúng.

Một vấn đề khác là tại sao vỏ có hai bộ kiểm tra khác nhau cho chuỗi và số. Đó là bởi vì chuỗi có thể không chứa gì ngoài chữ số, nhưng không thực sự là số. Ví dụ: nếu bạn thực hiện khoảng không quảng cáo, bạn có thể có một số bộ phận 00101. Bằng số, chúng bằng nhau, nhưng là chuỗi, chúng là hai chuỗi khác nhau. Không có cách nào cho kịch bản shell biết. Thay vào đó, bạn phải cho kịch bản lệnh biết nếu đó là so sánh số hoặc so sánh chuỗi.

Perl có vấn đề tương tự kể từ khi bạn không khai báo biến như số hoặc không phải số:

      Shell Script    Perl 
Boolean Operator  Numeric  String  Numeric String 
=================== =======  ======  ======= ====== 
Equals     -eq  =   ==   eq 
Not Equals    -ne  !=   !=   ne 
Greater Than   -gt  >   >   gt 
Less Than    -lt  <   <   lt 
Greater or Equals  -ge  >=   >=   ge 
Less Than or Equals -le  <=   <=   le 

Bạn có thể thử một vài điều khác:

$ echo "*" #Echos the asterisk 
$ echo *  #No quotes: Prints all files in current directory 

Thông báo một lần nữa vỏ nở* trước khi thực hiện lệnh echo. Đây là sự khác biệt chính giữa một kịch bản lệnh shell và một ngôn ngữ lập trình điển hình. Shell đầu tiên mở rộng (điền vào các biến môi trường, thay thế glob, chạy các lệnh con) trước khi nó thực sự thực hiện lệnh.

set -xv sẽ cho bạn biết lệnh nào đang được thực thi và cách vỏ mở rộng lệnh trước khi thực thi. Làm set +xv sẽ tắt tính năng đó. Chơi xung quanh với điều đó, và bạn sẽ sớm hiểu vỏ một chút tốt hơn.

Các vấn đề liên quan