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/logsendmail

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 中不工作的主要内容,如果未能解决你的问题,请参考以下文章

Cron 工作在每当 gem 中不起作用

Docker:Cronjob 不工作

docker ubuntu cron -f 不工作

相对路径在 cron PHP 脚本中不起作用

用于laravel的docker容器上的cron无法正常工作

具有 kerberos 安全性的 Sqoop 在 cron 中不起作用,抛出 GSSException