Bashの2つの文字列を比較する


22

ifbashスクリプトに次のブロックがあります。

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

に等しいifにもかかわらず、スクリプトの実行がブロックに入りません。私は何を間違えていますか?$PACKAGENAMEkakadu-v6_4-00902C


9
-eq整数の場合、文字列または正規表現(==または=~)をテストする必要があります:mywiki.wooledge.org/BashGuide/TestsAndConditionals
jasonwryan 14

jasonwryanこのリソースを見ていただきありがとうございます!
DemiSheep

回答:


31

-eq 2つの数値を比較する算術演算子です。

使用=(ポータブル/標準sh)、=~または==代わりに。

また、引用符を使用し${PACKAGENAME}ます。空白またはワイルドカード文字が含まれていると、複数の引数に分割され[、必要以上の引数が表示されるためです。一般的なbashの落とし穴のリストはこちらをご覧ください。

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

参照man bash、検索(/)のためにCONDITIONAL EXPRESSIONS


1
あ!ありがとうございました!出来た!私は明らかにこれで新人です。あなたの助けに感謝します!
DemiSheep

2
あなたは見たことがありtldp.org/LDP/Bash-Beginners-Guide/htmlを?それは非常に素晴らしいbashガイドであり、例と試験であなたを助けます:)。
polym

1
見てくれてありがとうpolym、リソースをありがとう!VIガイドの横にあるタブを開きます。:)
DemiSheep 14

4
二重括弧内では、単語の分割は行われないため、問題ありません[[ $PACKAGENAME == "kakadu..." ]]
グレンジャックマン14

4
でも、二重括弧内に、あなたがの右側に変数の展開二重引用符で囲む必要があることに注意してくださいしかし@glennjackman ===及び!=その辺はパターンではなく、文字列であるため、。たとえば、foo='*'; [[ whatever = $foo ]]はtrueです。
ジル「SO-悪であるのをやめる」14

6

交換する-eq== ブロックがこれを可能ならば、あなたのように: -

if [ ${PACKAGENAME} == kakadu-v6_4-00902C ]; then

        echo "successfully entered if block!!"

fi

5
引用することを忘れないでください!ここをご覧ください、理由:mywiki.wooledge.org/BashPitfalls#A.5B_.24foo_.3D_.22bar.22_.5D
polym 14

@polymちょっとありがとう、しかし私は働いていたミニマリストのバージョンを与えただけです;):D
初心者14

4

別の方法はそれらを無効にすることです:

: ${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

上記のブロックは最初に"$PACKAGENAME"値があるかどうかをテストし、そうでない場合はエラーで終了し、にエコー?'this'}stderrます。その親シェルがまだ存在する場合、テストは成功し、変数から「kakadu ...」文字列を削除した結果、-z空の文字列になるかどうかをテストします。表示されない場合は、エラーを再度出力し、シェルを終了します。この時点でブロックが実行された後もシェルがまだ存在している場合はそうではありません。

おそらく、この種のことは関数に実装するのが最適です。のような:

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
)

その関数を使用すると、システムが許可する数の引数を指定できます。2未満を指定すると、1が返され、にメッセージが送信されstderrます。2つ以上の引数を指定すると、すべてが文字列として扱われ、すべてが同じでnullでない場合は0が返され、そうでない場合は最初にチェックに失敗した引数番号が返されます。

あなたの場合、次のように使用できます:

{   
    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

さらに説明するために、別の関数を作成します。

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
}

デモ:

{  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
}  

出力:

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
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.