如何让Bash脚本自动在Docker容器内执行MySQL数据库恢复命令
解决Docker容器内自动执行MySQL恢复命令的问题
你的问题核心在于用了docker exec -ti参数——这个参数会启动交互式伪终端,导致脚本执行到这里就暂停,等你手动操作,后面的命令其实是在宿主机而非容器内执行的,自然没法完成自动恢复。
要实现自动化,我们需要让docker exec直接在容器内执行命令序列,不用进入交互式shell。下面是两种可行的修改方案:
方案1:用sh -c传递命令字符串
把容器内要执行的所有命令用引号包裹,作为参数传给docker exec的sh -c命令:
git clone git@<git_file>.git ${APIK_ROOT_DIRECTORY}/data/mysql/restore # 直接在容器内执行命令序列,无需交互式shell docker exec mysql_mysql_1 sh -c " cd /var/lib/mysql/restore echo 'CREATE DATABASE apik;USE apik;' | cat - apik.db.sql > temp && mv temp apik.db.sql mysql --user=root --password=\$MYSQL_ROOT_PASSWORD < apik.db.sql echo 'CREATE DATABASE apik_data;USE apik_data;' | cat - apik_data.db.sql > temp && mv temp apik_data.db.sql mysql --user=root --password=\$MYSQL_ROOT_PASSWORD < apik_data.db.sql echo 'USE apik;' | cat - apik.data.sql > temp && mv temp apik.data.sql mysql --user=root --password=\$MYSQL_ROOT_PASSWORD < apik.data.sql "
注意这里的\$MYSQL_ROOT_PASSWORD要加反斜杠转义,避免宿主机shell解析这个变量(它是容器内的环境变量)。
方案2:用Here-Doc传递命令(更易读)
如果命令序列比较复杂,推荐用Here-Doc语法,保持命令原有的格式,可读性更强:
git clone git@<git_file>.git ${APIK_ROOT_DIRECTORY}/data/mysql/restore # 使用Here-Doc向容器内的sh传递命令 docker exec mysql_mysql_1 sh << 'EOF' cd /var/lib/mysql/restore echo 'CREATE DATABASE apik;USE apik;' | cat - apik.db.sql > temp && mv temp apik.db.sql mysql --user=root --password=$MYSQL_ROOT_PASSWORD < apik.db.sql echo 'CREATE DATABASE apik_data;USE apik_data;' | cat - apik_data.db.sql > temp && mv temp apik_data.db.sql mysql --user=root --password=$MYSQL_ROOT_PASSWORD < apik_data.db.sql echo 'USE apik;' | cat - apik.data.sql > temp && mv temp apik.data.sql mysql --user=root --password=$MYSQL_ROOT_PASSWORD < apik.data.sql EOF
这里用'EOF'(单引号包裹)的目的是禁止宿主机shell替换容器内的环境变量,确保$MYSQL_ROOT_PASSWORD是容器内的变量。
关键注意点
- 移除
-ti参数:这个参数是给交互式操作准备的,自动化脚本不需要它,否则会导致脚本阻塞。 - 确认挂载路径:确保宿主机的
${APIK_ROOT_DIRECTORY}/data/mysql/restore已经正确挂载到容器的/var/lib/mysql/restore,否则容器内找不到SQL文件(你手动执行成功应该已经配置好了,但还是建议检查一下)。
内容的提问来源于stack exchange,提问作者Azykos
相关产品推荐
相关产品推荐

