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?


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.


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'


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
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.