Comparing two strings in Bash

136,271

Solution 1

-eq is an arithmetic operator, which compares two numbers.

Use = (portable/standard sh), =~ or == instead.

Also use quotes, because if ${PACKAGENAME} contains a whitespace or wildcard character, then it will be split into multiple arguments, which causes to make [ see more arguments than desired. See here a list of common bash pitfalls.

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

See man bash, search (/) for CONDITIONAL EXPRESSIONS.

Solution 2

Replace -eq with == so your if block would be this:-

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

        echo "successfully entered if block!!"

fi

Solution 3

Another way is to negate them:

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

The above block first tests if "$PACKAGENAME" has any value at all, and, if not it exits with error and echoes ?'this'} to stderr. If its parent shell still exists then the test has passed, and it next tests if removing your 'kakadu...' string from the variable results in an -z empty string. If it does not, then it again emits an error and exits the shell. If your shell still exists at this point anything after the block is executed, otherwise it is not.

Probably this sort of thing is best implemented in a function. Like:

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
)

With that function you can provide as many arguments as your system will allow. If you provide fewer than 2 it will return 1 and emit a message to stderr. If you provide 2 or more arguments it will treat all as strings and return 0 if all are identical and not null else it will return the argument number which first fails the check.

In your case it can be used like:

{   
    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

To demonstrate further I'll write another function:

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
}

DEMO:

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

OUTPUT:

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
Share:
136,271

Related videos on Youtube

DemiSheep
Author by

DemiSheep

Computer geek turned computer scientist.

Updated on September 18, 2022

Comments

  • DemiSheep
    DemiSheep almost 2 years

    I have the following if block in my bash script:

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

    The script execution is not entering my if block even though $PACKAGENAME is equal to kakadu-v6_4-00902C. What am I doing wrong?

  • DemiSheep
    DemiSheep almost 10 years
    Ah! Thank you! It worked! I am obviously a rookie at this. I'm grateful for your help!
  • polym
    polym almost 10 years
    Have you had a look at tldp.org/LDP/Bash-Beginners-Guide/html ? It's a very nice bash guide and will help you with examples and exams :).
  • polym
    polym almost 10 years
    Also have a look at the bash pitfalls link I've put into the updated answer. Happy coding :)!
  • polym
    polym almost 10 years
    Don't forget quoting! Have a look here, why: mywiki.wooledge.org/BashPitfalls#A.5B_.24foo_.3D_.22bar.22_.‌​5D
  • Angel Todorov
    Angel Todorov almost 10 years
    Within double brackets, no word splitting is done, so [[ $PACKAGENAME == "kakadu..." ]] is OK.
  • Gilles 'SO- stop being evil'
    Gilles 'SO- stop being evil' almost 10 years
    @glennjackman Beware however that even within double brackets, you need double quotes around variable expansions on the right-hand side of =, == and !=, because that side is a pattern, not a string. For example, foo='*'; [[ whatever = $foo ]] is true.
  • beginer
    beginer almost 10 years
    @polym hey thanks, but I just gave the minimalist version that was working ;) :D .
  • John B
    John B almost 10 years
    Although this is tagged with bash, it's worth noting the test can be POSIX shell compliant by doing = as == is a Bashism.