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

Docker Shell脚本执行mysql命令提示‘command not found’的原因排查

Docker脚本执行MySQL命令报错的排查与解决

我编写了一个Shell脚本,用于将setup_db.sql复制到Docker MySQL容器中并执行。在主机终端直接执行以下命令时完全正常:

docker exec -it $existingMySQLContainer bash -c "mysql -u root -proot < setup_db.sql"

但把这条命令放到脚本里执行时,却抛出错误:

bash: mysql -u root -proot < setup_db.sql: command not found

我尝试了各种双引号的写法调整,都没能解决问题。脚本完整内容如下:

#!/bin/sh

# 检查指定名称的容器是否存在
existingMySQLContainer=$(docker ps -a -q -f name="local-test-mysql-db")
if [ ! -z "$existingMySQLContainer" ]
then
    # 找到容器,删除以获取干净的数据库环境
    echo "Found existing local test db " $existingMySQLContainer
    docker rm -f $existingMySQLContainer
fi

docker run --name local-test-mysql-db -d -p 3310:3306 -e MYSQL_ROOT_PASSWORD=root mysql:8 

# 获取容器ID
existingMySQLContainer=$(docker ps -a -q -f name="local-test-mysql-db")
docker cp setup_db.sql $existingMySQLContainer:/setup_db.sql

docker exec -it $existingMySQLContainer bash -c '"mysql -u root -proot < setup_db.sql"'

问题根源

折腾半天后发现,根本不是引号的问题——而是容器启动后,MySQL服务还没完成初始化加载,我就立刻尝试执行SQL脚本了。此时MySQL服务尚未就绪,导致执行命令时出现看似"命令找不到"的异常。

解决方案

需要在脚本中添加等待逻辑,确保MySQL服务完全就绪后再执行SQL脚本。可以通过循环尝试连接MySQL来判断服务状态:

#!/bin/sh

# 检查指定名称的容器是否存在
existingMySQLContainer=$(docker ps -a -q -f name="local-test-mysql-db")
if [ ! -z "$existingMySQLContainer" ]
then
    echo "Found existing local test db " $existingMySQLContainer
    docker rm -f $existingMySQLContainer
fi

docker run --name local-test-mysql-db -d -p 3310:3306 -e MYSQL_ROOT_PASSWORD=root mysql:8 

existingMySQLContainer=$(docker ps -a -q -f name="local-test-mysql-db")
docker cp setup_db.sql $existingMySQLContainer:/setup_db.sql

# 等待MySQL服务就绪,循环尝试连接
until docker exec $existingMySQLContainer mysql -u root -proot -e "SELECT 1" > /dev/null 2>&1; do
    echo "等待MySQL服务启动中..."
    sleep 2
done

# 服务就绪后执行SQL脚本
docker exec $existingMySQLContainer bash -c "mysql -u root -proot < /setup_db.sql"

额外优化

  1. 简化命令写法:可以去掉bash -c的嵌套引号,直接执行MySQL命令,避免引号混淆:
docker exec $existingMySQLContainer mysql -u root -proot < /setup_db.sql
  1. 跳过文件复制步骤:通过管道直接将本地SQL文件内容传递给容器内的MySQL,省去docker cp操作:
cat setup_db.sql | docker exec -i $existingMySQLContainer mysql -u root -proot

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 03:05:49