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
docker exec is not working in cron
提问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.log
file either
我也没有在/root/cron.log
文件中看到任何错误
回答by VDR
Your docker exec
command 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/log
or sendmail
1./var/log
或sendmail
As crond
work as a daemon, without ability of failing, execution is more important than logging. Then by default, if something goes wrong, cron
will send a mail to $USER@localhost
reporting script output and errors.
作为crond
守护进程,没有失败的能力,执行比日志记录更重要。然后默认情况下,如果出现问题,cron
将发送邮件$USER@localhost
报告脚本输出和错误。
Have a look at /var/mail
or /var/spool/mail
for some mails, maybe
看看/var/mail
或/var/spool/mail
找一些邮件,也许
and at /etc/aliases
to 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 $PATH
is user's default pathand notroot default path(ie no */sbin
and 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 $PATH
initializer 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) cron
may 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/cronok
before the docker exec
call.
你确定你的脚本正在运行?touch /tmp/cronok
在docker exec
调用之前添加其他命令。
Don't forget that the crontab needs a newline at the end. Use crontab -e
to 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 mail
command.
使用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.
看看这是否会产生更好的工作。