bash docker exec 在 cron 中不起作用

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/37089033/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-18 14:36:36  来源:igfitidea点击:

docker exec is not working in cron

bashmeteordockercronmeteor-up

提问by user555

I have pretty simple command which is working fine standalone as a command or bash script but not when I put it in crontab

我有一个非常简单的命令,它可以作为命令或 bash 脚本独立工作,但当我把它放在 crontab 中时就不行了

40 05 * * * bash /root/scripts/direct.sh >> /root/cron.log

which has following line

其中有以下行

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/

I tried to change the url of script to /usr/bin/scirpts/no luck

我试图将脚本的 url 更改为/usr/bin/scirpts/没有运气

I even tried to run script directly in cron

我什至尝试在 cron 中直接运行脚本

26 08 * * * docker exec -it mongodb mongodump -d meteor -o /dump/ >> /root/cron.log

with no luck, any help appreciated.

没有运气,任何帮助表示赞赏。

EDIT

编辑

I don't see any errors in /root/cron.logfile either

我也没有在/root/cron.log文件中看到任何错误

回答by VDR

Your docker execcommand says it needs "pseudo terminal and runs in interactive mode" (-it flags) while cron doesn't attach to any TTYs.

您的docker exec命令说它需要“伪终端并以交互模式运行”(-it flags),而 cron 不附加到任何 TTY。

Try changing your docker exec command to this and see if that works?

尝试将您的 docker exec 命令更改为此,看看是否有效?

docker exec mongodb mongodump -d meteor -o /dump/

回答by Jason Hughes

for what it's worth I had this exact same problem. Fixing your PATH, changing permissions, and making sure you are running as the appropriate docker user are all good things, but that's not enough. It's going to continue failing because you are using "docker exec -it", which tells docker to use an interactive shell. Change it to "docker exec -t" and it'll work fine. There will be no log output anywhere telling you this, however. Enjoy!

对于它的价值,我遇到了完全相同的问题。修复您的 PATH、更改权限并确保您以适当的 docker 用户身份运行都是好事,但这还不够。它会继续失败,因为您正在使用“docker exec -it”,它告诉 docker 使用交互式 shell。将其更改为“docker exec -t”,它会正常工作。但是,任何地方都不会有日志输出告诉您这一点。享受!

回答by F. Hauri

cron debugging

定时调试

1. /var/logor sendmail

1./var/logsendmail

As crondwork as a daemon, without ability of failing, execution is more important than logging. Then by default, if something goes wrong, cronwill send a mail to $USER@localhostreporting script output and errors.

作为crond守护进程,没有失败的能力,执行比日志记录更重要。然后默认情况下,如果出现问题,cron将发送邮件$USER@localhost报告脚本输出和错误。

Have a look at /var/mailor /var/spool/mailfor some mails, maybe

看看/var/mail/var/spool/mail找一些邮件,也许

and at /etc/aliasesto see where root's mail are sents.

/etc/aliases查看 root 的邮件发送到哪里。

2. crond and $PATH

2. crond 和 $PATH

When you run a command by cron, have care that $PATHis user's default pathand notroot default path(ie no */sbinand other reserved path to super user tools).

当您通过 cron 运行命令时,请注意$PATH用户的默认路径不是root 默认路径(即*/sbin超级用户工具的no和其他保留路径)。

For this, the simplier way is to print your default path in the environment where everything run fine:

为此,更简单的方法是在一切正常的环境中打印默认路径:

echo $PATH

or patch your script from command line:

或从命令行修补脚本:

sed -e "2aPATH='$PATH'" -i /root/scripts/direct.sh

This will add current $PATHinitializer at line 2 in your script.

这将$PATH在脚本的第 2 行添加当前初始化程序。

Or this, will whipe from your script all other PATH=:

或者这个,将从你的脚本中鞭打所有其他PATH=

sed -e "s/PATH=[^ ]*\( \|$\)//;2aPATH='$PATH'" -i /root/scripts/direct.sh

3. Force logging

3. 强制记录

Add at top of your script:

在脚本顶部添加:

exec 1>/tmp/cronlog-$$.log
exec 2>/tmp/cronlog-$$.err

Try this:

尝试这个:

sed -e '1a\nexec 1>/tmp/cronlog-$$.log\nexec 2>/tmp/cronlog-$$.err' -i ~/scripts/direct.sh

Finalized script could look like:

最终的脚本可能如下所示:

#!/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/

Executable flag

可执行标志

If you run your script by

如果你运行你的脚本

40 05 * * * bash /root/scripts/direct.sh

no executable flag are required, but you must add them:

不需要可执行标志,但您必须添加它们:

chmod +x ~/scripts/direct.sh

if you want to run:

如果你想运行:

40 05 * * * /root/scripts/direct.sh

回答by mbarthelemy

1) Make sure this task is in the rootuser's crontab - it's probably the case but you didn't write it explicitly

1) 确保此任务在root用户的 crontab 中 - 可能是这种情况,但您没有明确地编写它

2) cronmay be unable to find bash. I would remove it and call directly your script after making it executable:

2)cron可能无法找到bash. 我会删除它并在使其可执行后直接调用您的脚本:

chmod 755 /root/scripts/direct.sh

and then set your crontab entry as 40 05 * * * /root/scripts/direct.sh 2>&1 >> /root/cron.log

然后将您的 crontab 条目设置为 40 05 * * * /root/scripts/direct.sh 2>&1 >> /root/cron.log

If it's still not working, then you should have some useful output in /root/cron.log

如果它仍然不起作用,那么你应该有一些有用的输出 /root/cron.log

回答by rdupz

Are you sure your script is running? Add an other command like touch /tmp/cronokbefore the docker execcall.

你确定你的脚本正在运行?touch /tmp/cronokdocker exec调用之前添加其他命令。

Don't forget that the crontab needs a newline at the end. Use crontab -eto edit it.

不要忘记 crontab 最后需要一个换行符。使用crontab -e进行编辑。

Restart the cron service and check the logs (grep -i cron /var/log/syslog).

重新启动 cron 服务并检查日志 ( grep -i cron /var/log/syslog)。

If your OS is redhat/centos/fedora, you should try with the username (root) between the frequency and the command.

如果您的操作系统是 redhat/centos/fedora,您应该尝试root在频率和命令之间使用用户名 ( )。

Check your mails with the mailcommand.

使用mail命令检查您的邮件。

Check the crontab permissions. chmod 644 /etc/crontab.

检查 crontab 权限。chmod 644 /etc/crontab.

Maybe you just don't want to reinvent the wheel.

也许你只是不想重新发明轮子

回答by SaintHax

Here's a few things I'd change-- first, capture STDERR along with STDOUT and remove the shell specification in cron-- use #! in your script instead.

以下是我要更改的一些内容——首先,捕获 STDERR 和 STDOUT 并删除 cron 中的 shell 规范——使用 #! 在你的脚本中。

40 05 * * * /root/scripts/direct.sh &>> /root/cron.log

40 05 * * * /root/scripts/direct.sh &>> /root/cron.log

Next, you are setting your PATH in the reverse order, and you are missing your shbang. I have no idea why you are defining SHELL as /bin/sh, when you are running bash, instead of dash. Change your script to this.

接下来,您以相反的顺序设置 PATH,并且您缺少 shbang。我不知道你为什么在运行 bash 而不是 dash 时将 SHELL 定义为 /bin/sh。将您的脚本更改为此。

#!/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/

See if that yields something better to work with.

看看这是否会产生更好的工作。