我正在运行一个docker容器与一个图像:
ubi8/ubi-minimal
cronjob路径正确且go包已安装:
crontab -l
*/2 * * * * go run /usr/local/src/script.go
文件具有正确的权限:
-rw-r-xr-x 1 root root 6329 Jun 16 15:10 script.go
但是crontab -e是这样的:
/bin/sh: /usr/bin/vi: No such file or directory
crontab: "/usr/bin/vi" exited with status 127
和
猫/etc/crontab
SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root
# For details see man 4 crontabs
# Example of job definition:
# .---------------- minute (0 - 59)
# | .------------- hour (0 - 23)
# | | .---------- day of month (1 - 31)
# | | | .------- month (1 - 12) OR jan,feb,mar,apr ...
# | | | | .---- day of week (0 - 6) (Sunday=0 or 7) OR sun,mon,tue,wed,thu,fri,sat
# | | | | |
# * * * * * user-name command to be executed
在dockerfile中添加crontab如下:
RUN crontab -l | { cat; echo "*/2 * * * * go run /usr/local/src/script.go"; } | crontab -
我认为这是正确的设置,不是吗?
crontab应该每2分钟执行一次脚本,但事实并非如此。此外,图像是最小的,我不能编辑任何文件,我只是从dockerfile中包含了一些文件权限。
如果需要改变任何路径从crontab我必须通过dockerfile做到这一点。
听起来很麻烦,可以考虑完全跳过cron守护进程,只在循环中睡觉
#!/bin/sh
while true; do
TIME_LOOP_START=$(date +%s) # integer time in seconds
script.go
# calculate offset for 2 minutes in seconds
sleep $(($TIME_LOOP_START + 120 - $(date +%s)))
done
改编自
- https://askubuntu.com/questions/852070/automatically-run-a-command-every-5-minutes
- 获取当前时间(以秒为单位),在Linux, Bash
您可能会发现,通过设置时间和目标可执行参数$1
$2
您需要启动cron守护进程。下面是我制作的一个Dockerfile来说明
FROM registry.access.redhat.com/ubi8/ubi-minimal
RUN microdnf update && microdnf install cronie
RUN crontab -l | { cat; echo "*/2 * * * * /usr/local/src/script.sh"; } | crontab -
COPY script.sh /usr/local/src/
CMD crond -n
请注意,CMD运行crond
与-n
选项,保持在前台拥挤。如果我们让它为守护进程,docker会看到进程已经结束,并会终止容器。
我没有使用go,而是编写了一个像这样的小shell脚本,名为script.sh
#/bin/sh
echo Hello from script >> ~/log.txt
每2分钟写入/root/log.txt。