cron, at, batchでジョブスケジューリングしよう

# はじめに
Linuxは**ジョブスケジューリング**によって、ジョブの実行タイミングを予約できます。（たとえば、深夜0時に自動的にシステム負荷を取得したいとか）
この記事では、**cronで定期的に実行するジョブを予約のしかた**、**at, batchで1回だけ実行するジョブの予約のしかた**について整理しました。

# crond
## cronで定期的に実行するジョブを予約しよう
cronで定期的に実行するジョブを予約するには、`crontab`コマンドを使用します。

### crontab -eでジョブの予約
crontabを`-e`オプションをつけて実行すると、エディタが開かれます。このエディタ上でジョブの予約をします。

```
$ crontab -e
```

**書式**

```
#min hour day month week job
*/5 0-1 * * * wall hello, cron!
0 2,3 * * * wall hello, cron!
```

`*/5 0-1 * * * wall hello, cron!`
毎日0時台〜1時台に5分間隔でジョブを実行する

`0 2,3 * * * wall hello, cron!`
毎日2時00分、3時00分にジョブを実行する

crontabで編集した後は、設定リロード、再起動の必要はありません。予約したタイミングで自動的にジョブが実行されます。

### crontab -lで予約済みのジョブを確認
crontabを`-l`オプションをつけて実行すると、予約済みのジョブ一覧を表示できます。

```
$ crontab -l
#min hour day month week job
*/5 0-1 * * * wall hello, cron!
0 2,3 * * * wall hello, cron!
```

## ユーザのアクセス制御
cronはユーザごとに使用制限をすることができます。`/etc/cron.deny`, `/etc/cron.allow`で管理します。デフォルトでは空の`/etc/cron.deny`だけが配置されています。

```
$ ls /etc/cron.deny
/etc/cron.deny
$ ls /etc/cron.allow
ls: /etc/cron.allow にアクセスできません: そのようなファイルやディレクトリはありません
```

- `/etc/cron.deny`のみ配置（デフォルト）
    - `/etc/cron.deny`に記載されているユーザ以外はcronをつかえる
    - デフォルトでは全てのユーザがcronをつかえる
- `/etc/cron.allow`と`/etc/cron.deny`を配置
    - `/etc/cron.allow`に記載されているユーザのみcronをつかえる
- `/etc/cron.allow`のみ配置
    - `/etc/cron.allow`に記載されているユーザのみcronをつかえる
- `/etc/cron.allow`と`/etc/cron.deny`を配置しない
    - 全てのユーザがcronをつかえる

# atd
## atで1回だけ実行するジョブを予約しよう
`at`コマンドで1回だけ実行するジョブを予約できます。

### atでジョブを予約する
`at hh:mm MMDDYY`でジョブを実行したいタイミングを指定します。
下記の例では、2018年12月23日 11時54分を指定しています。

```
$ at 11:54 122318
at> wall hello, at!
at> <EOT>
job 10 at Sun Dec 23 11:54:00 2018
```

`at>`プロンプトが表示されるので、実行したいジョブを入力します。
入力したら、`ctrl + d`で `at>`プロンプトを閉じます。

### at -lで予約したジョブ一覧を表示
atを`-l`オプションをつけて実行すると、予約したジョブの一覧を確認できます。
下記の例では、ジョブID 11のジョブが2018年12月23日 12時5分に実行するように予約されていることがわかります。

```
$ at -l
11	Sun Dec 23 12:05:00 2018 a papapapaper
```

`atq`コマンドでも、同じように予約したジョブ一覧を確認できます。

```
$ atq
11	Sun Dec 23 12:05:00 2018 a papapapaper
```

### at -cで予約したジョブの内容を表示
atを`-c`オプションをつけて実行すると、予約したジョブの内容を確認できます。
`at -c 11`のように引数にジョブIDを指定して使用します。

```
$ at -c 11
#!/bin/sh
# atrun uid=1000 gid=1000
# mail papapapaper 0
umask 2
XDG_SESSION_ID=108845; export XDG_SESSION_ID
(省略)
cd /home/papapapaper || {
	 echo 'Execution directory inaccessible' >&2
	 exit 1
}
${SHELL:-/bin/sh} << 'marcinDELIMITER5192e32c'
wall hello, at!
```

### at -dで予約したジョブの削除
atを`-d`オプションをつけて実行すると、予約したジョブを削除できます。
`at -c 12`のように引数にジョブIDを指定して使用します。
下記の例では、ジョブID 12のジョブを削除しています。

```
$ atq
12	Sun Dec 23 12:30:00 2018 a papapapaper
$ at -d 12
```

`atrm`コマンドでも、同じように予約したジョブを削除できます。

```
$ atq
12	Sun Dec 23 12:30:00 2018 a papapapaper
$ atrm 12
```

## batchで負荷が低下しているときに実行するジョブを予約しよう
`batch`でシステム負荷が低い状態のときに実行するジョブを予約できます。
システム負荷が低い状態でジョブを予約すると、すぐにジョブが実行されます。

```
$ batch
at> wall hello, batch!
at> <EOT>
job 14 at Sun Dec 23 12:16:00 2018
```

atと同じように`at>`プロンプトが表示されるので、実行したいジョブを入力します。
入力したら、`ctrl + d`で `at>`プロンプトを閉じます。
オプションもatと同様のものが使えます。

## ユーザのアクセス制御
atもcronと同じようにユーザごとに使用制限をすることができます。`/etc/at.deny`, `/etc/at.allow`で管理します。デフォルトでは空の`/etc/at.deny`だけが配置されています。

```
$ ls /etc/at.deny
/etc/at.deny
$ ls /etc/at.allow
ls: /etc/at.allow にアクセスできません: そのようなファイルやディレクトリはありません
```

- `/etc/at.deny`のみ配置（デフォルト）
    - `/etc/at.deny`に記載されているユーザ以外はatをつかえる
    - デフォルトでは全てのユーザがatをつかえる
- `/etc/at.allow`と`/etc/at.deny`を配置
    - `/etc/at.allow`に記載されているユーザのみatをつかえる
- `/etc/at.allow`のみ配置
    - `/etc/at.allow`に記載されているユーザのみatをつかえる
- `/etc/at.allow`と`/etc/at.deny`を配置しない
    - **rootのみatをつかえる**