如何让Bash脚本根据MySQL执行结果调用不同函数?
解决Bash脚本中MySQL执行后无法捕获返回值的问题
你的脚本核心问题是启用了set -e(遍历目录的代码块中,处理完ls后恢复了set -e)。当mysql命令执行失败返回非0状态时,set -e会触发脚本立即终止,导致status=$?及后续的条件判断代码完全没有机会执行。
以下是修复后的完整脚本,同时补充了缺失的函数实现和更安全的文件遍历逻辑:
ENV=localdev # 更新迁移表的示例函数(根据实际需求修改) update_migrations_table() { local sql_file="$1" local env="$2" echo "更新迁移表:标记 ${sql_file} 在 ${env} 环境下执行成功" # 替换为实际的迁移表更新SQL mysql -u "${DBUSER}" -p"${DBPASS}" -D "${DBNAME}" <<EOF INSERT INTO migrations (file_name, environment, executed_at) VALUES ('${sql_file}', '${env}', NOW()) ON DUPLICATE KEY UPDATE executed_at = NOW(); EOF } # 询问是否跳过迁移的示例函数(仅本地环境生效) ask_skip_migration() { local sql_file="$1" local env="$2" if [ "$env" != "localdev" ]; then echo "非本地环境,迁移执行失败,脚本终止" exit 1 fi read -p "迁移文件 ${sql_file} 执行失败,是否跳过?(y/n): " choice case "$choice" in y|Y ) echo "已跳过该迁移" ;; n|N ) echo "用户选择不跳过,脚本终止"; exit 1 ;; * ) echo "无效输入,脚本终止"; exit 1 ;; esac } exec_migration() { local dir="$1" local sql_file="$2" local env="$3" echo "Executing ${dir} - ${sql_file}" # 临时关闭set -e,避免mysql失败直接终止脚本 set +e mysql -u "${DBUSER}" -p"${DBPASS}" -D "${DBNAME}" < "$sql_file" status=$? # 恢复set -e(保持脚本全局的严格错误检查) set -e echo "status: $status" if [ "$status" -eq 0 ]; then echo '执行成功' update_migrations_table "$sql_file" "$env" else echo '执行失败' ask_skip_migration "$sql_file" "$env" fi } for DIR in cms lms; do echo "running migrations on ${DIR}" # 处理目录切换失败的情况 pushd ../../data/migrations/${DIR} || exit 1 DBNAME='mylmsdb' # 安全遍历SQL文件:避免文件名含空格的问题,无文件时自动跳过循环 shopt -s nullglob for SQL in *.sql; do exec_migration "${DIR}" "${SQL}" "${ENV}" done shopt -u nullglob popd done
关键修改说明
- 处理
set -e的影响:在exec_migration函数内部,执行mysql命令前临时关闭set +e,执行完成后恢复set -e,确保mysql执行失败时脚本不会直接终止,能继续执行状态判断逻辑。 - 安全遍历文件:替换
ls -1 *.sql的写法,改用shopt -s nullglob配合通配符遍历,避免文件名含空格时出现错误,同时无sql文件时会自动跳过循环。 - 增强错误处理:在
pushd后添加|| exit 1,避免目录不存在时脚本继续执行。 - 补充缺失函数:添加了
update_migrations_table和ask_skip_migration的示例实现,可根据实际业务逻辑调整。
测试效果
- 执行
My_test_migration_good.sql时,mysql返回0,触发迁移表更新逻辑。 - 执行
My_test_migration_bad.sql时,mysql返回非0,本地环境下会弹出询问是否跳过的提示;非本地环境则直接终止脚本。
内容的提问来源于stack exchange,提问作者Zectzozda
相关产品推荐
相关产品推荐

