批处理文件执行docker exec进入容器后后续命令被忽略如何解决
问题原因
批处理是逐行执行本地命令的,当你执行docker exec -it CONTAINER_NAME /bin/bash时,会启动容器内的交互式bash进程,此时批处理的执行流会直接阻塞在这个进程上,直到你手动退出容器内的bash会话,才会继续执行下一行代码。
而且就算等这个进程退出后再执行下一行的cd /var/opt/mssql/data,这个命令也是运行在本地Windows的cmd环境里,根本不是在容器内部执行,完全达不到预期效果。
你手动在打开的命令行窗口输入命令能正常运行,是因为你手动输入时操作的是已经成功启动的容器交互式终端,输入的内容会直接发送给容器内的shell,和批处理逐行调度本地命令的执行逻辑完全不同。
解决方案
根据你的实际需求选对应写法即可:
- 如果只是要自动执行容器内的备份操作,不需要保留交互式终端,直接把所有容器内要跑的命令作为参数传给docker exec即可,不需要单独启动交互式bash:
:: 去掉-t参数避免终端兼容问题,所有容器内操作写在bash -c后的引号中,用&&分隔 docker exec -i CONTAINER_NAME bash -c "cd /var/opt/mssql/data && 替换成你实际的数据库备份命令"
- 如果需要启动交互式终端后自动切到指定目录,方便后续手动操作,可以在启动bash时直接传入要执行的初始化命令,最后保留交互会话:
docker exec -it CONTAINER_NAME bash -c "cd /var/opt/mssql/data; exec bash"
末尾加exec bash的作用是执行完切目录的操作后,不直接退出容器会话,而是保留交互式终端供后续手动输入指令。
注意事项
不要把容器内需要执行的命令换行写在bat脚本的下一行,批处理不会自动把后续行的内容输入到容器的交互终端中,所有容器内的多步操作都要统一写在bash -c后面的引号内,用&&(前一步执行成功才跑后一步)或者;(不管前一步成不成都跑后一步)分隔。
内容的提问来源于stack exchange,提问作者user17432086
相关产品推荐
相关产品推荐

