docker exec 在 cron 中不工作
Posted
技术标签:
【中文标题】docker exec 在 cron 中不工作【英文标题】:docker exec is not working in cron 【发布时间】:2016-09-02 12:14:36 【问题描述】:我有一个非常简单的命令,它可以作为命令或 bash 脚本独立运行,但当我将它放入 crontab 时就不行了
40 05 * * * bash /root/scripts/direct.sh >> /root/cron.log
下面一行
PATH=$PATH:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin
SHELL=/bin/sh PATH=/bin:/sbin:/usr/bin:/usr/sbin:/root/
# Mongo Backup
docker exec -it mongodb mongodump -d meteor -o /dump/
我尝试将脚本的 url 更改为 /usr/bin/scirpts/
没有运气
我什至尝试直接在 cron 中运行脚本
26 08 * * * docker exec -it mongodb mongodump -d meteor -o /dump/ >> /root/cron.log
没有运气,感谢任何帮助。
编辑
我在/root/cron.log
文件中也没有看到任何错误
【问题讨论】:
不工作不是一个很有帮助的错误描述。请检查您的系统日志,并将任何错误消息和/或 /root/cron.log 的内容添加到您的问题中。 你能解释一下什么文件包含什么代码吗?我真的不明白什么是第一位的,甚至是写在哪里......顺便说一句,尝试将输出写入您的用户文件(而不是 root/cron.log)它曾经对我有用 第一个PATH=
没用,因为你在第二行覆盖了它。
究竟是什么不起作用?你期望垃圾场在哪里?我希望它保存在/dump/
目录中 - 但 inside 容器。也许您将该目录作为卷挂载添加到 mongodb 容器?
如果您足够关心发布赏金,当然您也应该足够关心将 stderr 重定向到文件并将这些日志包含在您的问题中。
【参考方案1】:
1) 确保此任务在 root 用户的 crontab 中 - 可能是这种情况,但您没有明确编写它
2) cron
可能无法找到 bash
。我会删除它并在使其可执行后直接调用您的脚本:
chmod 755 /root/scripts/direct.sh
然后将您的 crontab 条目设置为 40 05 * * * /root/scripts/direct.sh 2>&1 >> /root/cron.log
如果它仍然不起作用,那么您应该在 /root/cron.log
中有一些有用的输出
【讨论】:
感谢您的回复,但您的两个建议都不起作用,我也没有在日志文件中看到任何内容。 @user555 好吧,请将您从命令行运行时获得的输出添加到您的 OP。【参考方案2】:您确定您的脚本正在运行吗?在 docker exec
调用之前添加其他命令,例如 touch /tmp/cronok
。
不要忘记 crontab 最后需要一个换行符。使用crontab -e
进行编辑。
重启 cron 服务并检查日志 (grep -i cron /var/log/syslog
)。
如果你的操作系统是redhat/centos/fedora,你应该尝试在频率和命令之间使用用户名(root
)。
使用mail
命令检查您的邮件。
检查 crontab 权限。 chmod 644 /etc/crontab
.
也许你只是不想重新发明the wheel。
【讨论】:
【参考方案3】:这里有几件事我要改变——首先,捕获 STDERR 和 STDOUT 并删除 cron 中的 shell 规范——使用 #!而是在您的脚本中。
40 05 * * * /root/scripts/direct.sh &>> /root/cron.log
接下来,您以相反的顺序设置 PATH,但您缺少 shbang。我不知道为什么在运行 bash 时将 SHELL 定义为 /bin/sh,而不是 dash。把你的脚本改成这个。
#!/usr/bin/env bash
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/root
PATH=$PATH:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin
# Mongo Backup
docker exec -it mongodb mongodump -d meteor -o /dump/
看看这是否会产生更好的效果。
【讨论】:
【参考方案4】:您的 docker exec
命令说它需要“伪终端并以交互模式运行”(-it flags),而 cron 不附加到任何 TTY。
尝试将您的 docker exec 命令更改为此,看看是否有效?
docker exec mongodb mongodump -d meteor -o /dump/
【讨论】:
你是一个救生员! 可以保留-t
对于那些使用docker-compose
的用户,您需要添加 -T
标志,记录为:“禁用伪tty 分配。默认情况下docker-compose exec
分配一个 TTY。”
非常感谢...你救了我:D【参考方案5】:
cron 调试
1。 /var/log
或 sendmail
crond
作为守护进程工作,没有失败的能力,执行比日志记录更重要。然后默认情况下,如果出现问题,cron
会向$USER@localhost
发送邮件报告脚本输出和错误。
查看/var/mail
或/var/spool/mail
的一些邮件,也许
并在/etc/aliases
以查看根邮件的发送位置。
2。 crond 和$PATH
当您通过 cron 运行命令时,请注意 $PATH
是 用户的默认路径 并且 不是 root 默认路径(即不是*/sbin
和其他超级用户工具的保留路径)。
为此,更简单的方法是在一切正常的环境中打印您的默认路径:
echo $PATH
或从命令行修补您的脚本:
sed -e "2aPATH='$PATH'" -i /root/scripts/direct.sh
这将在脚本的第 2 行添加当前的 $PATH
初始化程序。
或者这个,会从你的脚本中删除所有其他PATH=
:
sed -e "s/PATH=[^ ]*\( \|$\)/\1/;2aPATH='$PATH'" -i /root/scripts/direct.sh
3。强制记录
在脚本顶部添加:
exec 1>/tmp/cronlog-$$.log
exec 2>/tmp/cronlog-$$.err
试试这个:
sed -e '1a\\nexec 1>/tmp/cronlog-$$.log\nexec 2>/tmp/cronlog-$$.err' -i ~/scripts/direct.sh
最终脚本可能如下所示:
#!/bin/bash
# uncomment two following lines to force log to /tmp
# exec 1>/tmp/cronlog-$$.log
# exec 2>/tmp/cronlog-$$.err
PATH='....' # copied from terminal console!
docker exec -it mongodb mongodump -d meteor -o /dump/
可执行标志
如果你运行你的脚本
40 05 * * * bash /root/scripts/direct.sh
不需要可执行标志,但您必须添加它们:
chmod +x ~/scripts/direct.sh
如果你想跑:
40 05 * * * /root/scripts/direct.sh
【讨论】:
【参考方案6】:对于它的价值,我遇到了同样的问题。修复您的 PATH、更改权限并确保您以适当的 docker 用户身份运行都是好事,但这还不够。它将继续失败,因为您使用的是“docker exec -it”,它告诉 docker 使用交互式 shell。将其更改为“docker exec -t”,它会正常工作。但是,任何地方都不会有日志输出告诉您这一点。享受吧!
【讨论】:
将docker exec -it
更改为 docker exec -t
对我有用!以上是关于docker exec 在 cron 中不工作的主要内容,如果未能解决你的问题,请参考以下文章