Comparar dos cadenas en Bash

22

Tengo el siguiente ifbloque en mi script bash:

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

La ejecución del script no está ingresando a mi ifbloque aunque $PACKAGENAMEsea ​​igual a kakadu-v6_4-00902C. ¿Qué estoy haciendo mal?

DemiSheep
fuente
99
-eqes cierto para los enteros, desea probar una cadena o expresión regular ( ==o =~): mywiki.wooledge.org/BashGuide/TestsAndConditionals
jasonwryan
Gracias. jasonwryan¡Echaré un vistazo a este recurso!
DemiSheep

Respuestas:

31

-eq es un operador aritmético, que compara dos números.

Uso =(portátil / estándar sh), =~o en su ==lugar.

También use comillas, porque si ${PACKAGENAME}contiene un espacio en blanco o un carácter comodín, se dividirá en varios argumentos, lo que hace que [vea más argumentos de los deseados. Vea aquí una lista de problemas comunes de bash.

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

Ver man bash, buscar ( /) para CONDITIONAL EXPRESSIONS.

polimero
fuente
1
Ah! ¡Gracias! ¡Funcionó! Obviamente soy un novato en esto. Estoy agradecido por tu ayuda!
DemiSheep
2
¿Has echado un vistazo a tldp.org/LDP/Bash-Beginners-Guide/html ? Es una muy buena guía de bash y te ayudará con ejemplos y exámenes :).
polym
1
Gracias polymecharé un vistazo, gracias por el recurso! Abriré esa pestaña junto a mi guía de VI. :)
DemiSheep
44
Dentro de los corchetes dobles, no se divide la palabra, por lo que [[ $PACKAGENAME == "kakadu..." ]]está bien.
Glenn Jackman
44
@glennjackman Tenga cuidado, sin embargo, que incluso entre corchetes dobles, necesita comillas dobles alrededor de expansiones variables en el lado derecho de =, ==y !=, porque ese lado es un patrón, no una cadena. Por ejemplo, foo='*'; [[ whatever = $foo ]]es cierto.
Gilles 'SO- deja de ser malvado'
6

Reemplace -eqpor == lo que su bloque if sería este: -

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

        echo "successfully entered if block!!"

fi
principiante
fuente
55
¡No olvides citar! Eche un vistazo aquí, por qué: mywiki.wooledge.org/BashPitfalls#A.5B_.24foo_.3D_.22bar.22_.5D
polym
@polym oye, gracias, pero acabo de dar la versión minimalista que estaba funcionando;): D.
principiante
4

Otra forma es negarlos:

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

Las primeras pruebas de bloque anterior si "$PACKAGENAME"tiene algún valor, y, si no se sale con error y ecos ?'this'}a stderr. Si su shell padre todavía existe, la prueba ha pasado, y luego prueba si eliminar la cadena 'kakadu ...' de la variable da como resultado una -zcadena vacía. Si no lo hace, vuelve a emitir un error y sale del shell. Si su shell aún existe en este punto, cualquier cosa después de que se ejecute el bloque, de lo contrario no lo es.

Probablemente este tipo de cosas se implemente mejor en una función. Me gusta:

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
)

Con esa función, puede proporcionar tantos argumentos como lo permita su sistema. Si proporciona menos de 2, devolverá 1 y emitirá un mensaje a stderr. Si proporciona 2 o más argumentos, tratará a todos como cadenas y devolverá 0 si todos son idénticos y no son nulos; de lo contrario, devolverá el número de argumento que primero falla la comprobación.

En su caso se puede usar como:

{   
    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

Para demostrar más, escribiré otra función:

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
}

MANIFESTACIÓN:

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

SALIDA:

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
mikeserv
fuente