如何在没有交互式编辑器的情况下自动使用Bash创建一个cron作业?

Raú*_*Roa 363 bash shell cron

crontab是否有一个参数来创建cron作业而不使用编辑器(crontab -e).如果是这样,那么代码会从Bash脚本创建一个cronjob?

dog*_*ane 507

您可以按如下方式添加到crontab:

#write out current crontab
crontab -l > mycron
#echo new cron into cron file
echo "00 09 * * 1-5 echo hello" >> mycron
#install new cron file
crontab mycron
rm mycron
Run Code Online (Sandbox Code Playgroud)

Cron线解释

* * * * * "command to be executed"
- - - - -
| | | | |
| | | | ----- Day of week (0 - 7) (Sunday=0 or 7)
| | | ------- Month (1 - 12)
| | --------- Day of month (1 - 31)
| ----------- Hour (0 - 23)
------------- Minute (0 - 59)
Run Code Online (Sandbox Code Playgroud)

来源nixCraft.

  • (crontab -l; echo"00 09**1-5 echo hello")| crontab - (160认同)
  • `(crontab -l; echo"00 09**1-5 echo hello")| crontab -` - 更容易复制Edo的衣服 (31认同)
  • 你应该使用tempfile或mktemp (14认同)
  • @MacUsers,`crontab -l`如果没有crontab则会失败,因此使用`&&`会使脚本无法将第一个条目添加到crontab中. (9认同)
  • 如果`crontab -l`失败,我建议改变`````&&`作为安全防范.所以,像:`(crontab -l && echo"0 0 0 0 0 some entry")| crontab -` (8认同)
  • 通过绕过安全防护来找到它:`(crontab -l 2>/dev/null; echo"0 0 0 0 0 some entry")| crontab -` (4认同)
  • @moeseth我还没有尝试过(我来自移动设备),但是类似的东西应该可以工作((crontab -l && echo“ 0 0 0 0 0 some entry” |排序| uniq)| crontab -` (3认同)
  • 这将避免重复:`! (crontab -l | grep -q "SCRIPT_FILENAME") && (crontab -l; echo "20 10 * * * SCRIPT_FILENAME") | (crontab -l | grep -q "SCRIPT_FILENAME") && (crontab -l; echo "20 10 * * * SCRIPT_FILENAME") | crontab-` (3认同)

The*_*sai 296

你可以在飞行中做到这一点

crontab -l | { cat; echo "0 0 0 0 0 some entry"; } | crontab -
Run Code Online (Sandbox Code Playgroud)

crontab -l列出当前的crontab作业,cat打印它,echo打印新命令crontab -并将所有打印的内容添加到crontab文件中.你可以通过做一个新的来看到效果crontab -l.

  • 不适用于我的Amazon EC2实例.相反,`(crontab -l; echo"00 09**1-5 echo hello")| crontab -`有效. (19认同)
  • 这看起来像[UUcatA]的候选者(http://porkmail.org/era/unix/award.html#cat). (11认同)
  • `crontab -l`列出当前的crontab作业,`cat`打印它,`echo`打印新命令,`crontab -`将所有打印的东西添加到crontab文件中.您可以通过执行新的`crontab -l`来查看效果 (9认同)
  • 谢谢,你能解释一下语法,还是指向一个解释它的网址? (3认同)
  • 为我服务.如果用户没有现有的crontab,你会看到`没有用于<username>的crontab,但无论如何都可以. (3认同)
  • 您可能希望在最后一个命令之前通过“ sort | uniq”进行传递,以避免重复crontab中的条目(尽管这可能会更改行顺序) (2认同)

Moo*_*tus 80

这个较短的文件不需要临时文件,它不受多次插入的影响,它允许您更改现有条目的计划.

说你有这些:

croncmd="/home/me/myfunction myargs > /home/me/myfunction.log 2>&1"
cronjob="0 */15 * * * $croncmd"
Run Code Online (Sandbox Code Playgroud)

要将其添加到crontab,没有重复:

( crontab -l | grep -v -F "$croncmd" ; echo "$cronjob" ) | crontab -
Run Code Online (Sandbox Code Playgroud)

要从crontab中删除它,无论其当前的时间表如何:

( crontab -l | grep -v -F "$croncmd" ) | crontab -
Run Code Online (Sandbox Code Playgroud)

笔记:

  • grep -F按字面意思匹配字符串,因为我们不希望将其解释为正则表达式
  • 我们也忽略了时间安排,只查找命令.这条路; 可以更改计划,而不存在向crontab添加新行的风险

  • 如果您的 bash 脚本具有“set -e”并且 crontab 列表为空,则此命令将不起作用。发生这种情况是因为`crontab -l | grep -v -F "$croncmd"` 与 `1` 一起存在,因此立即停止脚本。为了避免这种情况,您可以通过这种方式更新该行 `( crontab -l | grep -v -F "$COMMAND" || : ; echo "$JOB" ) | crontab-`。`|| :` 将确保在 crontab 为空时 `grep` 不会停止脚本。更多关于“:”的信息[这里](/sf/answers/225743731/)。 (5认同)
  • @moeseth:我显然在我的电脑上试过它(linux).我不建议随机不工作的东西:/ (2认同)
  • 顺便说一下,27个人不能错(截至今天).所以请说明为什么它不适用于您的设置,所以我们可以提供帮助. (2认同)
  • 这可能是OSX问题. (2认同)

Sto*_*tie 38

谢谢大家的帮助.把我在这里和其他地方找到的东西拼凑在一起我想出了这个:

代码

command="php $INSTALL/indefero/scripts/gitcron.php"
job="0 0 * * 0 $command"
cat <(fgrep -i -v "$command" <(crontab -l)) <(echo "$job") | crontab -
Run Code Online (Sandbox Code Playgroud)

我无法弄清楚如何在不重复自己的情况下消除对两个变量的需求.

command显然是我想安排的命令.job获取$command并添加调度数据.我在执行工作的代码行中分别需要两个变量.

细节

  1. 感谢duckyflip,我使用这个小重定向thingy(<(*command*))将输出crontab -l转换为fgrep命令的输入.
  2. fgrep然后过滤掉$command(-v选项)的任何匹配,不区分大小写(-i选项).
  3. 同样,小重定向thingy(<(*command*))用于将结果转换回cat命令的输入.
  4. cat命令还echo "$job"通过使用重定向thingy(<(*command*))再次接收(自解释).
  5. 所以过滤后的输出crontab -l和简单的echo "$job"组合,都是管道('|')crontab -到最后写的.
  6. 从那以后他们都过着快乐的生活!

简而言之:

这行代码过滤掉与命令匹配的任何cron作业,然后使用新的cron作业写出剩余的cron作业,实际上就像"添加"或"更新"功能.要使用它,您所要做的就是替换commandjob变量的值.

  • 如果您更喜欢传统的从左到右的管道方式,请将最后一行替换为:`crontab -l | fgrep -i -v"$ command"| { 猫; 回声"$ job"; } | crontab -l` (5认同)
  • 为了其他人阅读的好处,这种方法的优点是您可以多次运行它而不必担心crontab中的重复条目(与所有其他解决方案不同).这是因为`fgrep -v` (4认同)

duc*_*lip 26

编辑(固定覆盖):

cat <(crontab -l) <(echo "1 2 3 4 5 scripty.sh") | crontab -
Run Code Online (Sandbox Code Playgroud)

  • 请记住,Bash的进程替换吞噬了错误.如果`crontab -l`失败,但`crontab -`成功,你的crontab将是一个单行. (3认同)

Mik*_*osh 13

关于crontab的使用有很多好的答案,但没有提到更简单的方法,比如使用cron.

使用cron将利用位于的系统文件和目录/etc/crontab,/etc/cron.daily,weekly,hourly/etc/cron.d/:

cat > /etc/cron.d/<job> << EOF
SHELL=/bin/bash 
PATH=/sbin:/bin:/usr/sbin:/usr/bin 
MAILTO=root HOME=/  
01 * * * * <user> <command>
EOF
Run Code Online (Sandbox Code Playgroud)

在上面的例子中,我们创建了一个文件/etc/cron.d/,提供了成功执行命令的环境变量,并提供user了命令和command自身.此文件不应该是可执行文件,名称应仅包含字母数字和连字符(下面有更多详细信息).

为了给出一个彻底的答案,让我们来看看crontabvs 之间的区别cron/crond:

crontab -- maintain tables for driving cron for individual users
Run Code Online (Sandbox Code Playgroud)

对于那些想要在系统上的用户环境中运行工作的人来说,使用crontab可能非常有意义.

cron -- daemon to execute scheduled commands
Run Code Online (Sandbox Code Playgroud)

对于那些使用配置管理或想要为其他用户管理作业的人,在这种情况下我们应该使用cron.

从联机帮助页面中快速摘录为您提供了一些示例,说明了要做什么和不做什么:

/ etc/crontab和/etc/cron.d中的文件必须由root拥有,并且不能是group-或other-writable.与假脱机区域相反,/ etc/cron.d下的文件或/etc/cron.hourly,/etc/cron.daily,/etc/cron.weekly和/etc/cron.monthly下的文件也可能是符号链接,只要符号链接和它指向的文件都由root拥有./etc/cron.d下的文件不需要是可执行的,而/etc/cron.hourly,/etc/cron.daily,/etc/cron.weekly和/etc/cron.monthly下的文件也是如此,它们由运行部件运行(有关更多信息,请参阅运行部件(8)).

资料来源: http ://manpages.ubuntu.com/manpages/trusty/man8/cron.8.html

从系统角度来看,以这种方式管理crons更容易,也更具可扩展性,但并不总是最好的解决方案.

  • 值得一提的是,“&lt;job&gt;”不应包含文件扩展名。 (3认同)

Bra*_*y79 8

因此,在 Debian、Ubuntu 和许多类似的基于 Debian 的发行版中...

有一个 cron 任务串联机制,它接受一个配置文件,将它们捆绑起来并将它们添加到您正在运行的 cron 服务中。

您可以将文件放在 /etc/cron.d/somefilename 下,其中 somefilename 是您想要的任何内容。

sudo echo "0,15,30,45 * * * * ntpdate -u time.nist.gov" >> /etc/cron.d/vmclocksync
Run Code Online (Sandbox Code Playgroud)

让我们拆开这个:

sudo - 因为您需要提升权限才能更改 /etc 目录下的 cron 配置

echo - 在标准输出上创建输出的工具。printf, cat... 也能用

" - 在字符串开头使用双引号,您是专业人士

0,15,30,45 * * * * - 标准的 cron 运行计划,每 15 分钟运行一次

ntpdate -u time.nist.gov - 我想运行的实际命令

" - 因为我的第一个双引号需要一个伙伴来关闭正在输出的行

>> - 双重定向附加而不是覆盖*

/etc/cron.d/vmclocksync - vmclocksync 是我选择的文件名,它在 /etc/cron.d/


* 如果我们使用 > 重定向,我们可以保证我们只有一个任务条目。但是,我们可能会破坏现有文件中的任何其他规则。您可以自己决定是否可以使用 > 进行破坏,或者使用 >> 进行可能的重复是否适合您。或者,您可以做一些令人费解或涉及的事情来检查文件名是否存在,其中是否有任何内容,以及您是否要添加任何类型的重复项——但是,我有事情要做,我不能这样做你现在。


kvz*_*kvz 7

您可能正在自动执行此操作,并且您不希望单个作业添加两次.在这种情况下使用:

__cron="1 2 3 4 5 /root/bin/backup.sh"
cat <(crontab -l) |grep -v "${__cron}" <(echo "${__cron}")
Run Code Online (Sandbox Code Playgroud)

这仅适用于您使用BASH的情况.我不知道正确的DASH(sh)语法.

更新:如果用户还没有crontab,则此功能无效.一种更可靠的方式是:

(crontab -l ; echo "1 2 3 4 5 /root/bin/backup.sh") | sort - | uniq - | crontab - 
Run Code Online (Sandbox Code Playgroud)

或者,如果您的发行版支持它,您也可以使用单独的文件:

echo "1 2 3 4 5 /root/bin/backup.sh" |sudo tee /etc/crond.d/backup
Run Code Online (Sandbox Code Playgroud)

另一个SO问题中找到了那些.


小智 6

echo "0 * * * * docker system prune --force >/dev/null 2>&1" | sudo tee /etc/cron.daily/dockerprune
Run Code Online (Sandbox Code Playgroud)


小智 5

为了使用BASH脚本快速,轻松地创建/替换crontab,我使用了以下表示法:

crontab <<EOF
00 09 * * 1-5 echo hello
EOF
Run Code Online (Sandbox Code Playgroud)


Ger*_*ade 5

如果在那里找不到所需的字符串,则只编辑crontab的变体:

CMD="/sbin/modprobe fcpci"
JOB="@reboot $CMD"
TMPC="mycron"
grep "$CMD" -q <(crontab -l) || (crontab -l>"$TMPC"; echo "$JOB">>"$TMPC"; crontab "$TMPC")
Run Code Online (Sandbox Code Playgroud)


小智 5

(2>/dev/null crontab -l ; echo "0 3 * * * /usr/local/bin/certbot-auto renew") | crontab -
Run Code Online (Sandbox Code Playgroud)
cat <(crontab -l 2>/dev/null) <(echo "0 3 * * * /usr/local/bin/certbot-auto renew") | crontab -
Run Code Online (Sandbox Code Playgroud)

#写出当前的crontab

crontab -l > mycron 2>/dev/null
Run Code Online (Sandbox Code Playgroud)

#将新的 cron 回显到 cron 文件中

echo "0 3 * * * /usr/local/bin/certbot-auto renew" >> mycron
Run Code Online (Sandbox Code Playgroud)

#安装新的cron文件

crontab mycron

rm mycron
Run Code Online (Sandbox Code Playgroud)