Bash 基礎 Part 03 -- cron で分ごとに自動実行
Tags: crontab, linux, batch
Published: 2022-11-06 19:00:39



## why

エンジニアとして、自動実行をローカルでもできるようになりたかった

---

# crontab で分、時間、日、月ごとにコマンドを定期実行する

---

## crontab とは？

https://uxmilk.jp/50631

Ubuntu デフォルトで入っているコマンド。インストール不要。

---

## vim で cron を開けるようにする

https://superuser.com/questions/281617/change-default-text-editor-for-crontab-to-vim

vim で書くためには .bashrc などで

```php
export VISUAL=vim
export EDITOR=vim
```

VISUAL と EDITOR の環境変数を両方 vim にする。

---

## * * * * * date >> cronlog.txt で 1 min ごとに現在時刻をファイルに追加で書き込む

https://crontab.guru/every-1-minute

このサイトで GUI で出せる。

アスタリスク 5 つで最小単位の 1 min ごとらしい。

```php
crontab -e

  1 * * * * * date >> cronlog.txt                                                                                                                              
  2 # Edit this file to introduce tasks to be run by cron.
```

crontab -e で cron のファイルを開ける
ここに 1min ごとに cronlog.txt に 日付を書き込むコマンドを書いた。

```php
crontab -l

* * * * * date >> cronlog.txt
# Edit this file to introduce tasks to be run by cron.
```

crontab -l で cron のファイルの中身を cat できる。

```php
  1 2022年 11月  7日 月曜日 03:37:01 JST                                                                                                              
  2 2022年 11月  7日 月曜日 03:38:01 JST
  3 2022年 11月  7日 月曜日 03:39:01 JST
```

3 min 待ってみると、1 min ちょうどごとに時刻が記録されていた。

echo をしても標準出力されるる先は不明。
なのでログファイルに出せば結果を監視できる。

これで実行時刻と合わせて curl -v でリクエストすれば、簡単に定期処理が手元で実行できる。

---

## */2 * * * *  で 2min ごとに現在時刻を記録する

```
* * * * * 
```

分、時間、日、月、全て * だと every minute

```
*/2 * * * *
```

分を */2 にすると every 2 minute ( 2 分ごと )
なそうなので、試してみる。

```php
  1 2022年 11月  7日 月曜日 03:37:01 JST                                                                                                              
  2 2022年 11月  7日 月曜日 03:38:01 JST
  3 2022年 11月  7日 月曜日 03:39:01 JST
  4 2022年 11月  7日 月曜日 03:40:01 JST
  5 2022年 11月  7日 月曜日 03:42:01 JST
  6 2022年 11月  7日 月曜日 03:44:01 JST
~                                           
```

変更してからの時間では、2min ごとに実行されていた！

同様に 3 ~ 59 min まで分を開けて実行できるし

* */2 などにすれば 2時間ごと、2日ごとにもできるだろう。

---

## 平日のみ実行する

https://qiita.com/koara-local/items/79cb9c08e77ac9d94b1d

最後の列のは 0 -6 で設定できて、0 から
日、月、火、水、木、金、土
となる。なので 1-5 で設定すれば OK

https://stackoverflow.com/questions/31880057/schedule-a-conditional-job-in-jenkins-by-excluding-weekends

```cron
H 0 * * 1-5
```

Jenkins では他の兼ね合いもあるので、最初の分は 0 指定にせず、H (自由な時間) に設定すべきらしい。



---

## while と sleep で 1 秒ごとに時刻を記録する

https://stackoverflow.com/questions/9619362/running-a-cron-every-30-seconds

cron ではできないが
while でループを回せばできるらしい。

```php
#!/bin/env bash
while [ true ]; do                                                                                                                                    
 sleep 1
 date >> cronlog.txt
done                                     
```

cron の時と同じように時刻を記録するコマンドを動かすループを
everySec.sh という名前でつくり

```php
chmod 755 everySec.sh
```

実行権限を与え

```php
./everySec.sh
```

実行してしばらく待ち、止めて

cronlog.txt をみてみると

```php
  1 2022年 11月  7日 月曜日 03:49:24 JST                                                                                                              
  2 2022年 11月  7日 月曜日 03:49:25 JST
  3 2022年 11月  7日 月曜日 03:49:26 JST
```

1 sec 後に実行されているのを確認できた。

---

# まとめ

crontab -e で * * * * * {command} と書けば
1 min ごとにコマンドを実行できる

{command >> log.txt} でちゃんと実行されてるか確認できる

*/2 * * * * で 2 min ごとに実行できる

cron では最小単位は min だが、 while と sleep 1 でシェルを書けば 1 秒ごとに実行できる。