在Ubuntu 16.04 Docker镜像中通过Cron运行Go脚本无日志输出的问题排查
解决Cron触发Go脚本无日志输出的问题
你遇到的问题核心在于Cron执行环境和交互式Shell的差异——手动执行脚本一切正常,但Cron的默认工作目录、环境变量和你登录容器后的Shell环境不一样,这直接导致Go脚本无法正常执行,自然没有日志输出。下面是具体的排查和修复方案:
1. 先捕获错误信息,定位问题根源
首先你得让Cron执行脚本时的错误信息也输出到日志里,这样才能知道到底哪里出了问题。可以从两个地方修改:
- 方案一:修改
src/crontab.txt,把命令改成:
* * * * * /backup.sh >> /var/log/backup.log 2>&1
- 方案二:直接在
backup.sh里把Go命令的错误输出也重定向:
#!/bin/sh chmod 666 /var/log/backup.log /usr/lib/go-1.10/bin/go run /backup.go >> /var/log/backup.log 2>&1
这样如果Go命令执行失败(比如找不到文件),错误信息会被写入日志,帮你快速定位问题。
2. 修复Go脚本的路径问题
从你的Dockerfile来看,backup.go被ADD到了根目录/下,但Cron执行backup.sh时,默认工作目录是执行用户的HOME目录(比如root用户的/root)。这时候直接执行go run backup.go会找不到文件,因为当前目录下没有这个文件。
解决方法有两种:
- 方法一:在Go命令中使用绝对路径
修改backup.sh里的Go命令,指定backup.go的绝对路径:
/usr/lib/go-1.10/bin/go run /backup.go
- 方法二:在脚本开头切换到工作目录
在backup.sh的开头加上一行,切换到backup.go所在的根目录:
cd /
3. 验证Cron的环境变量(可选兜底)
虽然你用了Go的绝对路径,但有时候Cron的环境变量PATH可能不包含某些必要路径,你可以在crontab里显式设置环境变量,比如:
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/lib/go-1.10/bin * * * * * /backup.sh >> /var/log/backup.log 2>&1
这一步在你已经使用Go绝对路径的情况下可能不是必须的,但可以作为兜底方案。
4. 重启容器验证
修改完相关文件后,重新构建Docker镜像并启动容器,等待一分钟后查看/var/log/backup.log,应该就能看到Go脚本输出的Writing log日志了。
内容的提问来源于stack exchange,提问作者Lexx
相关产品推荐
相关产品推荐

