この記事のディレクトリ:
12.1 スケジュールされたタスクの構成
12.2 crontab ファイル
12 .3 crond コマンドのデバッグ
12.4 までの精度2 番目のタスクの計画
まず第一に、概念を理解する必要があります:
(1).crond はデーモン クラス プログラムであり、パスは /usr/sbin/crond です。 。デフォルトでは、crond がサービス モードまたは systemd モードで起動されると、デフォルトでバックグラウンド モードで起動されます。
(2).crondtab は crontab ファイルを管理するためのツールで、crontab ファイルはスケジュールされたタスクのエントリを定義するファイルです。
(3).crontab ファイルは、システムのスケジュールされたタスク ファイル /etc/crontab および /etc/cron.d/*、各ユーザーに固有のタスク ファイル /var/spool/cron/USERNAME など、多くの場所に存在します。
次に、crontab コマンドがあります:
-l:列出定时任务条目 -r:删除当前任务列表终端所有任务条目 -i:删除条目时提示是否真的要删除 -e:编辑定时任务文件,实际上编辑的是/var/spool/cron/*文件 -u:操作指定用户的定时任务
crontab -e コマンドを実行して、現在のユーザーの crontab ファイルを編集します。たとえば、root ユーザーの場合は、/var/spool を編集します。 /cron/root ファイル。たとえば、次の行を記述します。
* * * * * /bin/echo "the first cron entry" >>/tmp/crond.txt
これにより、echo コマンドが毎分実行され、その内容が /tmp/crond.txt ファイルに追加されます。
タスク プランでタスク エントリを定義する方法は、/etc/crontab ファイルを参照できます。
[root@server2 ~]# cat /etc/crontab SHELL=/bin/bashPATH=/sbin:/bin:/usr/sbin:/usr/binMAILTO=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
このファイルには 3 つの変数が定義されており、そのうちの 1 つは PATH であり、これは非常に重要です。最後に、タスク エントリの定義方法も示します:
(1)。各タスク エントリは 6 つのセクションに分かれており、各セクションはスペースで区切られています。これは、ここに追加のユーザー名セクションがあるためです。 /etc/crontab はシステムのスケジュールされたタスク ファイルですが、一般的なスケジュールされたタスクにはこのセクションがありません。
(2). 最初の 5 つのセグメントは時間設定セグメントであり、それぞれ「時間共有、日、月、週」を表します。その定義は、コマンドまたはスクリプト タスクのセグメントです。処刑されることになる。
(3) 時間定義セクションでは、「*」を使用して各単位、つまり毎分、毎時、毎日、毎月、曜日 (毎日) を示します。
(4) 各期間では、カンマ「,」を使用して列挙を表すことができます。たとえば、各時間の時間、30 分、30 分を表すように定義します。このタスクを 50 分間実行します。
(5)。各期間では、「-」を使用して範囲を定義でき、カンマと組み合わせて使用できます。たとえば、分セグメントが「00,20-30,50」と定義されている場合、タスクは正時、20 分から 30 分までの毎分、および 50 分に実行されることを意味します。
(6) 各期間では、時間を無視することを示すために「/」を使用します。たとえば、小期間に「0-13/2」が定義されている場合、それは「0/2/4/6/」を意味します。 8/10/12 インチのポイントは時間の定義を満たします。 「*/N」は頻度を示すためによく使用されます。たとえば、「00 */2 * * *」は、毎日 2 時間ごとの正時にタスクを実行することを意味します。
(7). 定義された日と週が競合する場合、複数回実行されます (* 記号による競合を除く)。たとえば、タスクは毎月 15 日に実行され、競合がない通常の状況では、タスクは水曜日と毎月 15 日に実行されます。ある月も水曜日なので、この日はタスクが 2 回実行されます。したがって、週と日の両方を同時に定義するタスクは避けるようにしてください。
(8). コマンド段落 (つまり、段落 6) では、パーセント記号「%」は改行の特別な意味を表しており、最初の % 以降のすべての文字列がコマンドとみなされますので、任意に使用することはできません。 .標準入力。
たとえば、次の定義:
* * * * * /bin/cat >>/tmp/crond.txt %"the first %%cron entry%"
このタスクの出力結果は次のようになります:
"the firstcron entry"
したがって、スケジュールされたタスクのエントリでファイル名が時間によって定義されている場合、%スラッシュエスケープを逆にする必要があります。例:
* * * * * cp /etc/fstab /tmp/`date +\%Y-\%m-\%d`.txt
注意が必要なもう 1 つの期間設定は、* 記号を使用すると、低レベルの時間が高レベルの時間を上書きすることです。たとえば、「* */2 * * *」では、タスクを 2 時間ごとに実行するのではなく、1 分ごとに実行することを意味します。ただし、分ビットは 1 分ごとに設定されます。したがって、タスクが毎分実行されることを意味します。同様に、分の桁の設定「*/5 */2 * * *」は時の桁の設定をオーバーライドし、5 分ごとに実行され、時の桁の設定「00」を無視することを示します。 */2 */5 * *" 日の設定に関係なく、タスクが 2 時間ごとの正時に実行されることを示します。
crondtab file为任务定义文件。
(1).在此文件中,空行会被忽略,首个非空白字符且以#开头的行为注释行,但#不能出现在行中。
(2).可以在crontab file中设置环境变量,方式为"name=value",等号两边的空格可随意,即"name = value"也是允许的。但value中出现的空格必须使用引号包围。
(3). 默认crond命令启动的时候会初始化所有变量,除了某几个变量会被crond daemon自动设置好,其他所有变量都被设置为空值。自动设置的变量包括SHELL=/bin/sh,以及HOME和LOGNAME(在CentOS上则称为USER),后两者将被默认设置为/etc/passwd中指定的值。其中SHELL和HOME可以被crontab file中自定义的变量覆盖,但LOGNAME不允许覆盖。当然,自行定义的变量也会被加载到内存。
(4).除了LOGNAME/HOME/SHELL变量之外,如果设置了发送邮件,则crond还会寻找MAILTO变量。如果设置了MAILTO,则邮件将发送给此变量指定的地址,如果MAILTO定义的值为空(MAILTO=""),将不发送邮件,其他所有情况邮件都会发送给crontab file的所有者。
(5).在系统定时任务文件/etc/crontab中,默认已定义PATH环境变量和SHELL环境变量,其中PATH=/sbin:/bin:/usr/sbin:/usr/bin。
(6).crond daemon每分钟检测一次crontab file看是否有任务计划条目需要执行。
很多时候写了定时任务却发现没有执行,或者执行失败,但因为crond是后台运行的,有没有任何提示,很难进行排错。但是可以让crond运行在前端并进行调试的。
先说明下任务计划程序crond的默认执行方式。
使用下面三条命令启动的crond都是在后台运行的,且都不依赖于终端。
[root@xuexi ~]# systemctl start crond.service [root@xuexi ~]# service crond start [root@xuexi ~]# crond
但crond是允许接受选项的。
crond [-n] [-P] [-x flags] 选项说明:-n:让crond以前端方式运行,即不依赖于终端。-P:不重设环境变量PATH,而是从父进程中继承。-x:设置调试项,flags是调试方式,比较有用的方式是test和sch,即"-x test"和"-x sch"。 :其中test调试将不会真正的执行,sch调试将可以看到等待时间。具体的见下面的示例。
先看看启动脚本启动crond的方式。
[root@server2 ~]# cat /lib/systemd/system/crond.service [Unit] Description=Command Scheduler After=auditd.service systemd-user-sessions.service time-sync.target [Service]EnvironmentFile=/etc/sysconfig/crond ExecStart=/usr/sbin/crond -n $CRONDARGSExecReload=/bin/kill -HUP $MAINPID KillMode=process [Install] WantedBy=multi-user.target
它的环境配置文件为/etc/sysconfig/crond,该文件中什么也没设置。
[root@server2 ~]# cat /etc/sysconfig/crond # Settings for the CRON daemon. # CRONDARGS= : any extra command-line startup arguments for crond CRONDARGS=
所有它的启动命令为:/usr/sbin/crond -n。但尽管此处加了"-n"选项,crond也不会前端运行,且不会依赖于终端,这是systemctl决定的。
在解释下如何进行调试。以下面的任务条目为例。
[root@server2 ~]# crontab -e* * * * * echo "hello world" >>/tmp/hello.txt
执行crond并带上调试选项test。
[root@server2 ~]# crond -x test debug flags enabled: test [4903] cron started log_it: (CRON 4903) INFO (RANDOM_DELAY will be scaled with factor 8% if used.) log_it: (CRON 4903) INFO (running with inotify support) log_it: (CRON 4903) INFO (@reboot jobs will be run at computer's startup.)log_it: (root 4905) CMD (echo "hello world" >>/tmp/hello.txt )
执行crond并带上调试选项sch。
[root@server2 ~]# crond -x sch debug flags enabled: sch [4829] cron started log_it: (CRON 4829) INFO (RANDOM_DELAY will be scaled with factor 73% if used.) log_it: (CRON 4829) INFO (running with inotify support) [4829] GMToff=28800log_it: (CRON 4829) INFO (@reboot jobs will be run at computer's startup.)[4829] Target time=1497950880, sec-to-wait=38 # 等待crond daemon下一次的检测,所以表示38秒后crond将检测crontab file user [root:0:0:...] cmd="echo "hello world" >>/tmp/hello.txt " [4829] Target time=1497950940, sec-to-wait=60Minute-ly job. Recording time 1497922081log_it: (root 4831) CMD (echo "hello world" >>/tmp/hello.txt )user [root:0:0:...] cmd="echo "hello world" >>/tmp/hello.txt "[4829] Target time=1497951000, sec-to-wait=60Minute-ly job. Recording time 1497922141log_it: (root 4833) CMD (echo "hello world" >>/tmp/hello.txt )
但要注意,在sch调试结果中的等待时间是crond这个daemon的检测时间,所以它表示等待下一次检测的时间,因此除了第一次,之后每次都是60秒,因为默认crond是每分钟检测一次crontab file的。例如,下面是某次的等待结果,在这几次等待检测过程中没有执行任何任务。
[4937] Target time=1497951720, sec-to-wait=18[4937] Target time=1497951780, sec-to-wait=60[4937] Target time=1497951840, sec-to-wait=60
还可以同时带多个调试方式,如:
[root@server2 ~]# crond -x test,schdebug flags enabled: sch test[4914] cron started log_it: (CRON 4914) INFO (RANDOM_DELAY will be scaled with factor 21% if used.) log_it: (CRON 4914) INFO (running with inotify support) [4914] GMToff=28800log_it: (CRON 4914) INFO (@reboot jobs will be run at computer's startup.)[4914] Target time=1497951540, sec-to-wait=9 user [root:0:0:...] cmd="echo "hello world" >>/tmp/hello.txt " [4914] Target time=1497951600, sec-to-wait=60Minute-ly job. Recording time 1497922741log_it: (root 4916) CMD (echo "hello world" >>/tmp/hello.txt )
这样在调试定时任务时间时,也不会真正执行命令。
默认情况下,crond执行的任务只能精确到分钟,无法精确到秒。但通过技巧,也是能实现秒级任务的。
(1).方法一:不太精确的方法
写一个脚本,在脚本中sleep3秒钟的时间,这样能实现每3秒执行一次命令。
[root@xuexi ~]# cat /tmp/a.sh#!/bin/bash # PATH="$PATH:/usr/local/bin:/usr/local/sbin"for ((i=1;i<=20;i++));dols /tmpsleep 3done
[root@xuexi ~]# cat /var/spool/cron/lisi* * * * * /bin/bash /tmp/a.sh
但是这样的方法不是最佳方法,因为执行命令也需要时间,且crond默认会有一个随机延时,随机延时由变量RANDOM_DELAY定义。
(2).方法二:在cron配置文件中写入多条sleep命令和其他命令。
[root@xuexi ~]# cat /var/spool/cron/lisi* * * * * ls /tmp* * * * * sleep 3 && ls /tmp* * * * * sleep 6 && ls /tmp* * * * * sleep 9 && ls /tmp* * * * * sleep 12 && ls /tmp* * * * * sleep 15 && ls /tmp* * * * * sleep 18 && ls /tmp* * * * * sleep 21 && ls /tmp* * * * * sleep 24 && ls /tmp* * * * * sleep 27 && ls /tmp* * * * * sleep 30 && ls /tmp …* * * * * sleep 57 && ls /tmp
这种方式很繁琐,但是更精确。如果定义到每秒级别就得写60行cron记录。
由此能看出,秒级的任务本就不是crond所擅长的。实际上能用到秒级的任务也比较少。
以上がLinux でのスケジュールされたタスクの説明の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。