Blog

cron目录

Content #

如果创建的脚本对于执行时间的精确性要求不高,则用预配置的cron脚本目录会更方便。预配置的基础目录共有4个:hourly、daily、monthly和weekly。 $ ls /etc/cron.*ly /etc/cron.daily: 0anacron apt-compat cracklib-runtime logrotate […] apport bsdmainutils dpkg man-db […]

/etc/cron.hourly:

/etc/cron.monthly: 0anacron

/etc/cron.weekly: 0anacron man-db update-notifier-common $ 如果你的脚本需要每天运行一次,那么将脚本复制到daily目录,cron就会每天运行它。

From #

Linux命令行与shell脚本编程大全

crontab

Content #

每个用户(包括root用户)都可以使用自己的cron时间表运行已安排好的任务。 Linux提供了crontab命令来处理cron时间表。要列出已有的cron时间表,可以用-l选项: $ crontab -l no crontab for christine $ 在默认情况下,用户的cron时间表文件并不存在。可以使用-e选项向cron时间表添加字段。在添加字段时,crontab命令会启动一个文本编辑器,使用已有的 cron时间表作为文件内容(如果时间表不存在,就是一个空文件)。

From #

Linux命令行与shell脚本编程大全

在每月的最后一天执行

Content #

因为无法设置一个dayofmonth值,涵盖所有月份的最后一天。常用的解决方法是加一个if-then语句,在其中使用date命令检查明天的日期是不是某个月份的第一天(01):

00 12 28-31 * * if [ "$(date +%d -d tomorrow)" = 01 ] ; then command ; fi

这行脚本会在每天中午12点检查当天是不是当月的最后一天(28~31),如果是,就由cron执行command。

另一种方法是将command替换成一个控制脚本(controlling script),在可能是每月最后一天的时候运行。控制脚本包含if-then语句,用于检查第二天是否为某个月的第一天。如果是,则由控制脚本发出命令,执行必须在当月最后一天执行的内容。

From #

Linux命令行与shell脚本编程大全

cron时间表

Content #

cron时间表通过一种特别的格式指定作业何时运行,其格式如下:

minutepasthour hourofday dayofmonth month dayofweek command

cron时间表允许使用特定值、取值范围(比如1~5)或者通配符(星号)来指定各个字段。如果想在每天的10:15运行一个命令,可以使用如下cron时间表字段:

15 10 * * * command

dayofmonth、month以及dayofweek字段中的通配符表明,cron会在每天10:15执行该命令。要指定一条在每周一的下午4:15(4:15 p.m.)执行的命令,可以使用军事时间(1:00 p.m.是13:00,2:00 p.m.是14:00,3:00 p.m.是15:00,以此类推),如下所示:

15 16 * * 1 command

可以使用三字符的文本值(mon、tue、wed、thu、fri、sat、sun)或数值(0或 7代表周日,6代表周六)来指定dayofweek字段。

这里还有另外一个例子。要想在每月第一天的中午12点执行命令,可以使用下列字段:

00 12 1 * * command

dayofmonth字段指定的是月份中的日期值(1~31)。

命令列表必须指定要运行的命令或脚本的完整路径。你可以像在命令行中那样,添加所需的任何选项和重定向符:

15 10 * * * /home/christine/backup.sh > backup.out

cron程序会以提交作业的用户身份运行该脚本,因此你必须有访问该脚本(或命令)以及输出文件的合理权限。

From #

Linux命令行与shell脚本编程大全

在每月的最后一天执行

sub:cron

Content #

Linux系统使用cron程序调度需要定期执行的作业。cron在后台运行,并会检查一个特殊的表(cron时间表),从中获知已安排执行的作业。

cron时间表 crontab cron目录 anacron程序

删除作业(atrm)

Content #

一旦知道了哪些作业正在作业队列中等待,就可以用atrm命令删除等待中的作业。指定要删除的作业号即可: $ atq 1 Thu Jun 18 16:11:00 2020 a christine 5 Fri Jun 19 16:00:00 2020 a christine 6 Fri Jun 19 16:53:00 2020 a christine 7 Thu Jun 18 20:30:00 2020 a christine 8 Thu Jun 18 17:54:00 2020 a christine $ $ atrm 5 $ $ atq 1 Thu Jun 18 16:11:00 2020 a christine 6 Fri Jun 19 16:53:00 2020 a christine 7 Thu Jun 18 20:30:00 2020 a christine 8 Thu Jun 18 17:54:00 2020 a christine $ 只能删除自己提交的作业,不能删除其他人的。

...

列出等待的作业(atq)

Content #

atq命令可以查看系统中有哪些作业在等待: $ at -M -f tryatout.sh teatime warning: commands will be executed using /bin/sh job 5 at Fri Jun 19 16:00:00 2020 $ $ at -M -f tryatout.sh tomorrow warning: commands will be executed using /bin/sh job 6 at Fri Jun 19 16:53:00 2020 $ $ at -M -f tryatout.sh 20:30 warning: commands will be executed using /bin/sh job 7 at Thu Jun 18 20:30:00 2020 $ $ at -M -f tryatout.sh now+1hour warning: commands will be executed using /bin/sh job 8 at Thu Jun 18 17:54:00 2020 $ $ atq 1 Thu Jun 18 16:11:00 2020 a christine 5 Fri Jun 19 16:00:00 2020 a christine 6 Fri Jun 19 16:53:00 2020 a christine 7 Thu Jun 18 20:30:00 2020 a christine 8 Thu Jun 18 17:54:00 2020 a christine $ 作业列表中显示了作业号、系统运行该作业的日期和时间,以及该作业所在的作业队列。

...

获取at命令调度的作业的输出

Content #

当在Linux系统中运行at命令时,显示器并不会关联到该作业。Linux系统反而会将提交该作业的用户email地址作为STDOUT和STDERR。任何送往STDOUT或STDERR 的输出都会通过邮件系统传给该用户。

来看一个在CentOS发行版中使用at命令调度作业的例子: $ cat tryat.sh #!/bin/bash

echo “This script ran at $(date +%B%d,%T)” echo echo “This script is using the $SHELL shell.” echo sleep 5 echo “This is the script’s end.”

exit $ $ at -f tryat.sh now warning: commands will be executed using /bin/sh job 3 at Thu Jun 18 16:23:00 2020 $ at命令会显示分配给作业的作业号以及为作业安排的运行时间。-f选项指明使用哪个脚本文件。now指示at命令立刻执行该脚本。

注意:无须在意at命令输出的警告消息,因为脚本的第一行是#!/bin/bash,该命令会由bash shell执行。

使用email作为at命令的输出极不方便。at命令通过sendmail应用程序发送email。如果系统中没有安装sendmail,那就无法获得任何输出。因此在使用at命令时,最好在脚本中对STDOUT和STDERR进行重定向,如下例所示: $ cat tryatout.sh #!/bin/bash

outfile=$HOME/scripts/tryat.out

echo “This script ran at $(date +%B%d,%T)” > $outfile echo >> $outfile echo “This script is using the $SHELL shell.” >> $outfile echo >> $outfile sleep 5 echo “This is the script’s end.” >> $outfile

...

at命令的格式

Content #

at命令的基本格式非常简单:

at [-f filename] time

在默认情况下,at命令会将STDIN的输入放入队列。你可以用-f选项指定用于从中读取命令(脚本文件)的文件名。 time选项指定了你希望何时运行该作业。如果指定的时间已经过去,那么at命令会在第二天的同一时刻运行指定的作业。

指定时间的方式非常灵活。at命令能识别多种时间格式。

  • 标准的小时和分钟,比如10:15。
  • AM/PM指示符,比如10:15 PM。
  • 特定的时间名称,比如now、noon、midnight或者teatime(4:00 pm)。

除了指定运行作业的时间,也可以通过不同的日期格式指定特定的日期。

  • 标准日期,比如MMDDYY、MM/DD/YY或DD.MM.YY。
  • 文本日期,比如Jul 4或Dec 25,加不加年份均可。
  • 时间增量。
  • Now + 25 minutes
  • 10:15 PM tomorrow
  • 10:15 + 7 days

提示:at命令可用的日期和时间格式有很多种,具体参见 /usr/share/doc/at/timespec文件。

在使用at命令时,该作业会被提交至作业队列。作业队列保存着通过at命令提交的待处理作业。针对不同优先级,有52种作业队列。作业队列通常用小写字母 az和大写字母AZ来指代,A队列和a队列是两个不同的队列。

注意:在几年前,batch命令也能指定脚本的执行时间。这是个很独特的命令,因为它可以安排脚本在系统处于低负载时运行。现在,batch命令只不过是一个脚本而已(/usr/bin/batch),它会调用at命令将作业提交到b队列中。

作业队列的字母排序越高,此队列中的作业运行优先级就越低(谦让度更大)。在默认情况下,at命令提交的作业会被放入a队列。如果想以较低的优先级运行作业,可以用-q选项指定其他的队列。如果相较于其他进程你希望你的作业尽可能少地占用CPU,可以将其放入z队列。

From #

Linux命令行与shell脚本编程大全

sub:at命令

Content #

at命令允许指定Linux系统何时运行脚本。该命令会将作业提交到队列中,指定 shell何时运行该作业。

at的守护进程atd在后台运行,在作业队列中检查待运行的作业。

atd守护进程会检查系统的一个特殊目录(通常位于/var/spool/at或/var/spool/cron/atjobs),从中获取at命令提交的作业。在默认情况下,atd守护进程每隔60秒检查一次这个目录。如果其中有作业,那么atd守护进程就会查看此作业的运行时间。如果时间跟当前时间一致,就运行此作业。

at命令的格式 获取at命令调度的作业的输出 列出等待的作业(atq) 删除作业(atrm)