为何docker exec
无法执行容器内的脚本?!
这个困扰我将近一年的问题,总算被解开了。
WHY?
首先,解释为什么要执行容器内的脚本?原生环境不支持的工具,或者不想安装在原生环境的工具,是可以这么玩的。比如:我的MySQL安装在docker里面,要备份里面的数据,就需要docker exec
去执行容器的脚本命令,使用mysqldump
来实现我的功能。
例如:
docker exec -it mysql-server /bin/bash -c "/usr/bin/mysqldump -u$db_user -p$db_pass $db_name > $output"
至于crontab
,大家都知道这是个计划任务调度服务。在里面设置cron表达式,即可定时去执行脚本命令,非常方便地实现了自动备份。
问题来了!
以上脚本,我手动自行是完全没有问题的,百试百灵。可一旦使用crontab,它却罢工了!这简直令人百思不得琪姐~~~
解决方案
耽搁了一整年,今天终于下定决心,准备把这个问题解决了。
上网查了一通资料,然后发挥爱迪生找电灯灯丝的精神,测试实践了无数次后,终于恍然大悟。原来就这么简单就能搞定了!
实际上,上面的脚本之所以不能被crontab
执行,是因为-it
这个参数的缘故。只要去掉它一切就好了!
docker exec mysql-server /bin/bash -c "/usr/bin/mysqldump -u$db_user -p$db_pass $db_name > $output"
-it是什么鬼?
在 docker exec -it
命令中,-it
其实是两个独立的选项:
- -i 代表(Interactive)表示以交互模式运行容器中的命令。
- -t 代表(Terminal)表示进入容器后会分配一个伪终端。
简单来说,就是打开一种终端界面给我自己敲命令,而不是直接执行我预设的命令。crontab表示:我的上帝,虽然自己寄生在Terminal里面,但是并不会用Terminal啊!
于是,它便撂挑子不干了!这就是人和“人机”的区别,所以去掉这两个参数,不要为难crontab
。然后,Everything will be OK!