Bash: no se puede ingresar si incluso la condición es verdadera

2 minutos de lectura

Estoy creando un script que hará una copia de seguridad de una base de datos de WordPress. He creado la función necesaria para el volcado de MySQL:

function db_backup {
    read -r -p "Dump the database? [Y/n]: " response
    if [[ $response =~ ^([yY][eE][sS] || [yY])$ ]]
    then
        mysqldump -h $1 -u $2 -p$3 $4 > $4.sql

        if [[ $? == 0 ]]
        then
            printf "Database %s dumped successfuly in %s.sql\n" ${db_name} ${db_name}
            return 0
        else
            printf "Database backup %bfailed%b\n" ${red} ${reset}
            return 1
        fi  
    else
        return 1
    fi  
}

Cuando Y o Yes/yEs/yeS/YES/yes es hitter, no ingresa en el bloque if true y no se crea ningún volcado 🙁 Los detalles de la base de datos son correctos y el volcado está disponible, pero no puedo entrar en la condición SI.

  • Use comillas alrededor de la expresión regular, por ejemplo: [[ $response =~ "^([yY][eE][sS] || [yY])$" ]]

    – edi9999

    04/10/2015 a las 15:21


  • Su expresión regular coincidirá (sin distinción entre mayúsculas y minúsculas: comillas agregadas para fines de formato) "yes " (con un espacio final) o " y" (con un espacio inicial) o la cadena vacía ""… ¿Es eso lo que quieres?

    – gniourf_gniourf

    04/10/2015 a las 15:25


Intenta usar un case declaración:

db_backup()
{
    read -r -p "Dump the database? [Y/n]: " response

    case "$response" in
    y|Y|yes|Yes|YES)
        mysqldump -h $1 -u $2 -p$3 $4 > $4.sql

        if [[ $? == 0 ]]
        then
             printf "Database %s dumpedy in %s.sql\n" ${db_name} ${db_name}
             return 0
        else
             printf "Database backup %bfailed%b\n" ${red} ${reset}
             return 1
        fi
        ;;
    esac
    return 1

}

  • shopt -s nocasematch también puede ser útil aquí.

    –Etan Reisner

    04/10/2015 a las 15:31

  • ¡Su solución ha hecho el trabajo! ¡Gracias a los demás que atendieron mi pregunta también!

    – Georgi Tsvetanov Tsenov

    5 oct 2015 a las 15:28

Sus coincidencias de expresiones regulares (sin distinción entre mayúsculas y minúsculas: comillas agregadas para fines de formato) "yes " (con un espacio final) o " y" (con un espacio inicial) o la cadena vacía ""1.

Escribe esto en su lugar:

if [[ $response =~ ^([yY][eE][sS]|[yY])$ ]]

o mejor

if [[ $response =~ ^[yY]([eE][sS])?$ ]]

También puedes usar globos:

if [[ $response = [yY]?([eE][sS]) ]]

(con Bash<4.1 necesitas shopt -s extglob). También puedes convertir response a minúsculas:

if [[ ${response,,} = y?(es) ]]

(la ${var,,} la expansión de parámetros apareció en Bash 4.0).


1 y lo gracioso es que read (con el valor predeterminado IFS) elimina los espacios iniciales y finales… por lo que es imposible tener una coincidencia con una cadena que no esté vacía.

avatar de usuario
AsymLabs

¿Por qué no transformar primero la respuesta en mayúsculas y luego compararla con Y o SÍ? Por ejemplo, haz lo siguiente:

if [[ ${response^^} =~ ^(Y|YES)$ ]]; then ... fi

Esto tiene la ventaja de que no necesitas pensar en las posibles combinaciones de mayúsculas/minúsculas, se detectan todas. Además, en lugar de:

if [[ $? == 0 ]]; then ... fi

Solo puedes hacer:

if [[ $? ]]; then ... fi

Para las pruebas de verdad, el resultado de [[ 0 ]] es cierto, mientras que el resultado de (( 0 )) Es falso.

Considere algunas simplificaciones, para mejorar la legibilidad, como

function db_backup {
    read -r -p "Dump the database? [Y/n]: " response
    if [[ ${response^^} =~ ^(Y|YES)$ ]]
    then
        if mysqldump -h $1 -u $2 -p$3 $4 > $4.sql
        then
            printf "Database %s dumped successfuly in %s.sql\n" ${db_name} ${db_name}
            return 0
        else
            printf "Database backup %bfailed%b\n" ${red} ${reset}
            return 1
        fi  
    else
        return 1
    fi  
}

  • @gniourf_gniourf: Regex anclado, como se recomienda, gracias.

    – AsymLabs

    04/10/2015 a las 22:00

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad