システムのcrontab （cronとanacronの違い）

以前に記事にしたユーザごとのcrontabとは別にシステム用のcrontabファイル（`/etc/crontab`&`/etc/anacrontab`）もある。
システムのcrontanはrootユーザーしか制御できない。

ユーザーごとのcrontabまとめ記事は以下参照
https://qiita.com/yuzo_____/items/1b8af6e04ffa2baa1cab

## 2種類のシステムcrontab(crontab & anacrontab)

CentOS 5以前はcronがスケジュール管理に使われていたが、
CentOS6以降、anacronも使えるようになりより機能が増えた。

cronパッケージがインストールされているか確認。
```
[root@localhost prac]# rpm -qa | grep cron
crontabs-1.11-17.20190603git.el8.noarch
cronie-1.5.2-6.el8.x86_64
cronie-anacron-1.5.2-6.el8.x86_64
```

crontab・anacrontabファイルをそれぞれ確認
```
[root@localhost prac]# ls -l /etc/{crontab,anacrontab}
-rw-r--r--. 1 root root 541  4月 20  2022 /etc/anacrontab
-rw-r--r--. 1 root root 451  5月 19  2021 /etc/crontab
```

## cronとanacronの違い

①遅延実行
cron:サーバの電源落ちている間はタスクを実行しない。
anacron:サーバの電源落ちても、anacronはタスクを遅らせて実行する。

②スケジュールの周期の最短単位
cron:1分毎・1時間毎などの細かい指定ができる
anacron:1日単位の指定のみ

よって使い分けて利用することが多い。

## anacrontabファイルを確認

```:/etc/anacrontab
      1 # /etc/anacrontab: configuration file for anacron
      2 
      3 # See anacron(8) and anacrontab(5) for details.
      4 
      5 SHELL=/bin/sh
      6 PATH=/sbin:/bin:/usr/sbin:/usr/bin
      7 MAILTO=root
      8 # the maximal random delay added to the base delay of the jobs
      9 RANDOM_DELAY=45
     10 # the jobs will be started during the following hours only
     11 START_HOURS_RANGE=3-22
     12 
     13 #period in days   delay in minutes   job-identifier   command
     14 1       5       cron.daily              nice run-parts /etc/cron.dai        ly
     15 7       25      cron.weekly             nice run-parts /etc/cron.wee        kly
     16 @monthly 45     cron.monthly            nice run-parts /etc/cron.mon        thly

```
14行目の意味は
・「1日おきにシステム起動後5分たってから、`/etc/cron.daily`を実行しろ。
実行した日付はcron.daily = /var/spool/anacron/cron.dailyに書いておけ」という意味。

anacronがランダムにジョブの実行タイミングをずらす理由は、SVの負荷分散を行うため。
又、メンテナンスで一時的にサーバダウンしていても、起動したときに貯まっていたプログラムが
順次実行されることで手動で実行する手間も省けるメリットがある。

## anacronが最短で1日周期の指定のみになっていることを設定ファイルで確認する

hourlyジョブは、`/etc/cron.d/0hourly`に定義されている

```:/etc/cron.d/0hourly
1 # Run the hourly jobs
      2 SHELL=/bin/bash
      3 PATH=/sbin:/bin:/usr/sbin:/usr/bin
      4 MAILTO=root
      5 01 * * * * root run-parts /etc/cron.hourly
```
5行目
「1分毎にetc/cron.hourlyを実行しろ」と記載

/etc/cron.hourly配下にOanacronを確認

```
[root@localhost prac]# ls /etc/cron.hourly
0anacron
[root@localhost prac]# vi -R /etc/cron.hourly/0anacron
```

```:/etc/cron.hourly/0anacron
      1 #!/bin/sh
      2 # Check whether 0anacron was run today already
      3 if test -r /var/spool/anacron/cron.daily; then
      4     day=`cat /var/spool/anacron/cron.daily`
      5 fi
      6 if [ `date +%Y%m%d` = "$day" ]; then
      7     exit 0
      8 fi
      9 
     10 # Do not run jobs when on battery power
     11 online=1
     12 for psupply in AC ADP0 ; do
     13     sysfile="/sys/class/power_supply/$psupply/online"
     14 
     15     if [ -f $sysfile ] ; then
     16         if [ `cat $sysfile 2>/dev/null`x = 1x ]; then
     17             online=1
     18             break
     19         else
     20             online=0
     21         fi
     22     fi
     23 done
     24 if [ $online = 0 ]; then
     25     exit 0
     26 fi
     27 /usr/sbin/anacron -s
~                              
```

（3行目~8行目）前回のcron.daily実行時から日付が変わっていなければanacronは実行しない。
つまり1日一回しか動かさないことが定義されている。


## 指定したディレクトリ内にある複数のシェルスクリプトまとめて実行する`run-parts`コマンド

pracディレクトリに3つシェルスクリプト作成
```
[root@localhost ~]# echo "pwd" > prac/test1
[root@localhost ~]# echo "date" > prac/test2
[root@localhost ~]# echo "cal" > prac/test3
```
実行権744と環境パスを追加（割愛）

run-partsコマンドでまとめて実行
```
[root@localhost ~]# run-parts prac
prac/test1:
/root

prac/test2:
2022年 10月 30日 日曜日 00:44:39 JST

prac/test3:
      10月 2022     
日 月 火 水 木 金 土
                   1
 2  3  4  5  6  7  8
 9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31  
```

## まとめ

### cron

・指定したスケジュール(日時・曜日・時・分の粒度で時間を指定)にジョブを実行する
・指定した時刻に実行できなかった場合、次回の指定時刻まで待つ必要がある。

### anacron

・指定したスケジュールにランダムな遅延を挿入してジョブを実行
・指定した時刻に実行できなかった場合、実行できなかったジョブを自動で再実行する機能がある。
・/etc/anacrontabでジョブ指定可能。rootユーザでしか設定できない


以上。