So sánh hai chuỗi trong Bash


22

Tôi có ifkhối sau trong tập lệnh bash của mình:

if [ ${PACKAGENAME} -eq kakadu-v6_4-00902C ]; then
  echo "successfully entered if block!!"
fi

Việc thực thi tập lệnh không vào ifkhối của tôi mặc dù $PACKAGENAMEbằng kakadu-v6_4-00902C. Tôi đang làm gì sai?


9
-eqđúng với số nguyên, bạn muốn kiểm tra chuỗi hoặc regex ( ==hoặc =~): mywiki.wooledge.org/BashGuide/TestsAndCond điều kiện
jasonwryan

Cảm ơn jasonwryantôi sẽ xem tài nguyên này!
DemiSheep

Câu trả lời:


31

-eq là một toán tử số học, so sánh hai số.

Sử dụng =(di động / tiêu chuẩn sh), =~hoặc ==thay vào đó.

Cũng sử dụng dấu ngoặc kép, vì nếu ${PACKAGENAME}chứa ký tự khoảng trắng hoặc ký tự đại diện, thì nó sẽ được chia thành nhiều đối số, điều này khiến cho việc [nhìn thấy nhiều đối số hơn mong muốn. Xem ở đây một danh sách các cạm bẫy bash phổ biến.

if [ "${PACKAGENAME}" = 'kakadu-v6_4-00902C' ]; then
    echo "successfully entered if block!!"
fi

Xem man bash, tìm kiếm ( /) cho CONDITIONAL EXPRESSIONS.


1
À! Cảm ơn bạn! Nó đã làm việc! Tôi rõ ràng là một tân binh ở đây. Tôi biết ơn sự giúp đỡ của bạn!
DemiSheep

2
Bạn đã xem tldp.org/LDP/Bash-Beginners-Guide/html chưa? Đó là một hướng dẫn bash rất hay và sẽ giúp bạn với các ví dụ và bài kiểm tra :).
polym

1
Cảm ơn polymtôi sẽ xem, cảm ơn tài nguyên! Tôi sẽ mở tab đó bên cạnh hướng dẫn VI của tôi. :)
DemiSheep

4
Trong dấu ngoặc kép, không có phân tách từ nào được thực hiện, vậy [[ $PACKAGENAME == "kakadu..." ]]là ổn.
glenn jackman

4
@glennjackman Cẩn thận tuy nhiên rằng ngay cả trong dấu ngoặc kép, bạn cần dấu ngoặc kép xung quanh mở rộng biến ở phía bên tay phải của =, ==!=, vì bên đó là một mô hình, không phải là một chuỗi. Ví dụ, foo='*'; [[ whatever = $foo ]]là đúng.
Gilles 'SO- ngừng trở nên xấu xa'


4

Một cách khác là phủ nhận chúng:

: ${PACKAGENAME:?'$PACKAGENAME variable is empty!'} #emits error and exits
[ -z "${PACKAGENAME#kakadu-v6_4-00902C}" ] || { #if var - str not empty do block
    echo '$PACKAGENAME is not kakadu-v6_4-00902C' 
    exit 1
} >&2

Khối trên các bài kiểm tra đầu tiên nếu "$PACKAGENAME"có bất kỳ giá trị nào cả, và, nếu không muốn nói nó thoát với lỗi và tiếng vang ?'this'}đến stderr. Nếu lớp vỏ mẹ của nó vẫn tồn tại thì thử nghiệm đã vượt qua và thử nghiệm tiếp theo nếu loại bỏ chuỗi 'kakadu ...' của bạn khỏi biến sẽ dẫn đến một -zchuỗi trống. Nếu không, nó lại phát ra lỗi và thoát khỏi trình bao. Nếu shell của bạn vẫn tồn tại vào thời điểm này bất cứ điều gì sau khi khối được thực thi, nếu không thì không.

Có lẽ loại điều này được thực hiện tốt nhất trong một chức năng. Như:

argeq() ( i= : ${2?^MERR: not enough parameters!} #$#>=2 || quit w/ err ^M == \r
    z() { return $((${#1}>0)) ; } #return 1 if ${#1}>0 else 0
    until z "${2+?}" $((i=i+1)) #until $2 is not set...
    do  ! z "$1" && z "${1#"$2"}" || #$1 != '' && $1 - $2 == '' or...
        exit $((i${1:++1})) #exit $? == failed arg count
    shift ; done #shift away one param ; continue loop
)

Với chức năng đó, bạn có thể cung cấp nhiều đối số như hệ thống của bạn sẽ cho phép. Nếu bạn cung cấp ít hơn 2, nó sẽ trả về 1 và phát ra thông báo stderr. Nếu bạn cung cấp 2 hoặc nhiều đối số, nó sẽ coi tất cả là các chuỗi và trả về 0 nếu tất cả đều giống hệt nhau và không có giá trị nào khác, nó sẽ trả về số đối số trước tiên không kiểm tra.

Trong trường hợp của bạn, nó có thể được sử dụng như:

{   
    PACKAGENAME='kakadu-v6_4-00902C'
    argeq "$PACKAGENAME" kakadu-v6_4-00902C &&
        echo "kakadu-v6_4-00902C == $PACKAGENAME" ||
        echo failure
    ! argeq "${PACKAGENAME#*-}" kakadu-v6_4-00902C &&
        echo "kakadu-v6_4-00902C != ${PACKAGENAME#*-}" ||
        echo failure
}

###OUTPUT###
kakadu-v6_4-00902C == kakadu-v6_4-00902C
kakadu-v6_4-00902C != v6_4-00902C

Để chứng minh thêm tôi sẽ viết một chức năng khác:

aeqecho() { i=$((i+1)) #inc for line#
    argeq "$@" && echo "$i : yay" || #allswell or
    ! e=$? ${2+:} return || #save $?; ! exclusive || to drop ERRs
    echo "$i : shite - arg$e failed" #report failure
}

BẢN GIỚI THIỆU:

{  i= s=string
   aeqecho $s #1
   aeqecho $s $s #2
   aeqecho "$s $s" #3
   aeqecho "$s $s" "${s} string" #4
   aeqecho "${s}1" $s string #5
   aeqecho "" "" "" #6
   aeqecho "" "$s" $s #7
   aeqecho 1 "${s#$s}1" $((2-1)) #8                     
   aeqecho $s $s $s $s $s $s $s $s $s $s $s $s stng #9  
   aeqecho $s $s $s $s $s $s $s $s $s $s $s $s string #10
}  

ĐẦU RA:

ERR: not enough parameters!
2 : yay
ERR: not enough parameters!
4 : yay
5 : shite - arg2 failed
6 : shite - arg1 failed
7 : shite - arg1 failed
8 : yay
9 : shite - arg13 failed
10 : yay
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.