Bash:即使条件为真也无法进入
Bash: Unable to enter into if even the condition is true
我正在构建一个脚本来备份 WordPress 数据库。
我已经创建了 MySQL 转储所需的函数:
function db_backup {
read -r -p "Dump the database? [Y/n]: " response
if [[ $response =~ ^([yY][eE][sS] || [yY])$ ]]
then
mysqldump -h -u -p > .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
}
当 Y 或 Yes/yEs/yeS/YES/yes 被击中时 - 它不会进入 if true 块,并且不会创建转储 :( 数据库详细信息正确并且转储在手边,但我不能进入 IF 条件。
尝试使用 case
语句:
db_backup()
{
read -r -p "Dump the database? [Y/n]: " response
case "$response" in
y|Y|yes|Yes|YES)
mysqldump -h -u -p > .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
}
您的正则表达式匹配(不区分大小写——为格式化目的添加引号)"yes "
(尾随 space)或 " y"
(前导 space)或空字符串 ""
1.
改为这样写:
if [[ $response =~ ^([yY][eE][sS]|[yY])$ ]]
甚至更好
if [[ $response =~ ^[yY]([eE][sS])?$ ]]
你也可以使用 globs:
if [[ $response = [yY]?([eE][sS]) ]]
(Bash<4.1 你需要 shopt -s extglob
)。您还可以将 response
转换为小写:
if [[ ${response,,} = y?(es) ]]
(${var,,}
参数扩展出现在 Bash 4.0)。
1 有趣的是 read
(默认为 IFS
)去除了前导和尾随 spaces……所以它是不可能与非空字符串匹配。
为什么不先将响应转换为全部大写,然后再与 Y 或 YES 进行比较,例如:
if [[ ${response^^} =~ ^(Y|YES)$ ]]; then ... fi
这样做的好处是你不需要考虑upper/lowercase的可能组合,它们都会被检测到。另外,而不是:
if [[ $? == 0 ]]; then ... fi
你可以这样做:
if [[ $? ]]; then ... fi
对于真值检验,[[ 0 ]]
的结果为真,而(( 0 ))
的结果为假。
为了可读性考虑一些简化,例如
function db_backup {
read -r -p "Dump the database? [Y/n]: " response
if [[ ${response^^} =~ ^(Y|YES)$ ]]
then
if mysqldump -h -u -p > .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
}
我正在构建一个脚本来备份 WordPress 数据库。 我已经创建了 MySQL 转储所需的函数:
function db_backup {
read -r -p "Dump the database? [Y/n]: " response
if [[ $response =~ ^([yY][eE][sS] || [yY])$ ]]
then
mysqldump -h -u -p > .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
}
当 Y 或 Yes/yEs/yeS/YES/yes 被击中时 - 它不会进入 if true 块,并且不会创建转储 :( 数据库详细信息正确并且转储在手边,但我不能进入 IF 条件。
尝试使用 case
语句:
db_backup()
{
read -r -p "Dump the database? [Y/n]: " response
case "$response" in
y|Y|yes|Yes|YES)
mysqldump -h -u -p > .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
}
您的正则表达式匹配(不区分大小写——为格式化目的添加引号)"yes "
(尾随 space)或 " y"
(前导 space)或空字符串 ""
1.
改为这样写:
if [[ $response =~ ^([yY][eE][sS]|[yY])$ ]]
甚至更好
if [[ $response =~ ^[yY]([eE][sS])?$ ]]
你也可以使用 globs:
if [[ $response = [yY]?([eE][sS]) ]]
(Bash<4.1 你需要 shopt -s extglob
)。您还可以将 response
转换为小写:
if [[ ${response,,} = y?(es) ]]
(${var,,}
参数扩展出现在 Bash 4.0)。
1 有趣的是 read
(默认为 IFS
)去除了前导和尾随 spaces……所以它是不可能与非空字符串匹配。
为什么不先将响应转换为全部大写,然后再与 Y 或 YES 进行比较,例如:
if [[ ${response^^} =~ ^(Y|YES)$ ]]; then ... fi
这样做的好处是你不需要考虑upper/lowercase的可能组合,它们都会被检测到。另外,而不是:
if [[ $? == 0 ]]; then ... fi
你可以这样做:
if [[ $? ]]; then ... fi
对于真值检验,[[ 0 ]]
的结果为真,而(( 0 ))
的结果为假。
为了可读性考虑一些简化,例如
function db_backup {
read -r -p "Dump the database? [Y/n]: " response
if [[ ${response^^} =~ ^(Y|YES)$ ]]
then
if mysqldump -h -u -p > .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
}