Bash: impossible to enter even if the condition is true

I am creating a script that will backup the WordPress database. I created the function needed to dump 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 } 

When Y or Yes / yEs / yeS / YES / yes is an attacker, it is not included in the if true block and no dump is created :( The data in the database is correct and the dump continues, but I cannot enter the IF condition.

+5
source share
3 answers

Try using the case :

 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 } 
+5
source

Match regular expression (case insensitive formatting quotes) "yes " (with trailing space) or " y" (with leading space) or empty string "" 1 .

Instead, write:

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

or even better

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

You can also use globes:

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

(with Bash <4.1 you need shopt -s extglob ). You can also convert response to lowercase:

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

(the extension of the parameter ${var,,} appeared in Bash 4.0).


1 and it’s funny that read (with IFS by default) separates leading and trailing spaces ... so it is impossible to match a non-empty string.

+3
source

Why not transform the response to all caps first, and then compare with Y or YES, for example, do:

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

This has the advantage that you do not need to think about possible upper / lower case combinations, they are all detected. In addition, instead of:

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

You can simply do:

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

For truth tests, the result [[ 0 ]] is true, while the result (( 0 )) is false.

Consider some simplifications for readability, such as

 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 } 
0
source

Source: https://habr.com/ru/post/1232907/


All Articles