You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让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

关键修改说明

  1. 处理set -e的影响:在exec_migration函数内部,执行mysql命令前临时关闭set +e,执行完成后恢复set -e,确保mysql执行失败时脚本不会直接终止,能继续执行状态判断逻辑。
  2. 安全遍历文件:替换ls -1 *.sql的写法,改用shopt -s nullglob配合通配符遍历,避免文件名含空格时出现错误,同时无sql文件时会自动跳过循环。
  3. 增强错误处理:在pushd后添加|| exit 1,避免目录不存在时脚本继续执行。
  4. 补充缺失函数:添加了update_migrations_table和ask_skip_migration的示例实现,可根据实际业务逻辑调整。

测试效果

  • 执行My_test_migration_good.sql时,mysql返回0,触发迁移表更新逻辑。
  • 执行My_test_migration_bad.sql时,mysql返回非0,本地环境下会弹出询问是否跳过的提示;非本地环境则直接终止脚本。

内容的提问来源于stack exchange,提问作者Zectzozda

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 11:37:37