Day18 - 初識 Crontab

Crontab

前言

看到現在,你也應該學了不少知識了,你應該會發現有些系統好像都會「自動」去做某些事情,所以接下來將會來介紹例行性工作排程 (crontab) 這個東西。

Crontab 是什麼?

不知道你有沒有一種習慣,也就是固定每天要做的事情,例如說每天早上起床後都會刷牙洗臉,或是每天晚上睡覺前都會刷牙洗臉,這些事情都是你每天都會做的事情,而且都是固定的時間去做,這就是一種工作排程。

很難有感覺吧?畢竟這舉例太過於生活化了,讓我換另一個方式去形容,假設你今天是一個公司的老闆,你每年可能都要替公司舉辦團康、員工旅遊、開發會議、年終獎金發放等等,這些事情都是你每年都會做的事情,但這些事情實在有夠多,依照人腦來講,你就很難記得每一件事情要在什麼時候做,所以你就會把這些行程寫在 Google 日曆上,接著 Google 日曆就會在你設定的時間提醒你,這就是一種工作排程。

那麼為什麼會提到工作排程呢?因為我們實戰開發上其實也會用到這個技巧,所以這一篇我們將會來介紹 Node.js 中該如何實現 Crontab 的功能。

Note
題外話一下,Linux 中有兩種排程工具,一種是 at,另一種就是 crontab,而 crontab 是比較常用的,所以這一篇就以 crontab 來做介紹;Linux 一個自由和開放原始碼的類 UNIX 作業系統。

Crontab 格式

你以為馬上就可以來認識 Crontab 了嗎?

不,你還得先認識 Crontab 的格式,因為 Crontab 的格式是一個很重要的概念,所以你必須要先了解它。

首先,我們先來看一下 Crontab 的範例格式:

1
* * * * *

呼攏你

oh,別擔心,我並沒有耍你的意思,這個格式其實就是 Crontab 的格式,而這個格式又可以分成五個部分,分別是:

  • 分鐘 (Minute)
  • 小時 (Hour)
  • 日期 (Day)
  • 月份 (Month)
  • 星期 (Week)

那麼以前面剛剛寫的範例格式來講,在 Crontab 中的意思就是「每分鐘、每小時、每天、每月、每週」,也就是說,這個格式就是代表每分鐘都會執行一次。

假設現在是 2023/08/31 21:12 那就代表著,這個 Crontab 會在…

  • 2023/08/31 21:13
  • 2023/08/31 21:14
  • 2023/08/31 21:15…

以此類推,每分鐘都會執行一次。

那麼如果我們希望每半小時執行一次的話,那就可以這樣寫:

1
*/30 * * * *

這樣會跑的時間就會是…

  • 2023/08/31 21:30
  • 2023/08/31 22:00
  • 2023/08/31 22:30…

以此類推,每半小時都會執行一次。

那如果我們期望是每天的 12:00 執行一次的話,那就可以這樣寫:

1
0 12 * * *

這樣會跑的時間就會是…

  • 2023/09/01 12:00
  • 2023/09/02 12:00
  • 2023/09/03 12:00…

當然,還有一種很特殊的狀況,也就是每個月的一號的下午三點執行一次,那就可以這樣寫:

1
0 15 1 * *

這樣會跑的時間就會是…

  • 2023/09/01 15:00
  • 2023/10/01 15:00
  • 2023/11/01 15:00…

Note
crontab 的時間是採用 24 小時制。

那如果我們期望是特定日期呢?crontab 也做得到,例如一年一度的聖誕節,那就可以這樣寫:

1
0 0 25 12 *

這樣會跑的時間就會是…

  • 2023/12/25 00:00
  • 2024/12/25 00:00
  • 2025/12/25 00:00…

很有趣吧?那如果今天是希望每個禮拜三早上九點呢?那就可以這樣寫:

1
0 9 * * 3

這樣會跑的時間就會是…

  • 2023/09/06 09:00
  • 2023/09/13 09:00
  • 2023/09/20 09:00…

Note
crontab 的星期是從 0 開始,0 代表星期日,1 代表星期一,以此類推。

那如果今天是希望每個禮拜一到禮拜五早上九點呢?那就可以這樣寫:

1
0 9 * * 1-5

超有趣的吧?crontab 其實非常的靈活,你可以依照你的需求去做設定,而且 crontab 也有一些特殊的符號,例如…

  • *:代表任意值
  • ,:代表分隔符號
  • -:代表範圍
  • /:代表間隔

因此 crontab 也會被稱為「crontab 計畫表達式」,因為撰寫方式其實與表達式很像,底下我也提供一個簡單的圖來說明:

crontab

當然,crontab 還有一些特殊的符號,例如 @reboot,這個符號代表著系統開機時就會執行,用法其實很簡單,例如我們原本是寫這樣:

1
0 9 * * 1-5

那如果我們希望系統開機時就會執行的話,就可以這樣寫:

1
@reboot

直接把原本的格式替換掉就可以了。

當然這些是屬於比較特殊的排程,其他還有…

  • @yearly:每年的 1 月 1 日 00:00 執行一次,如同 0 0 1 1 *
  • @annually:同 @yearly
  • @monthly:每月的 1 日 00:00 執行一次,如同 0 0 1 * *
  • @weekly:每週的星期日 00:00 執行一次,如同 0 0 * * 0
  • @daily:每天 00:00 執行一次,如同 0 0 * * *
  • @midnight:同 @daily
  • @hourly:每小時 00 分執行一次,如同 0 * * * *

那麼如果你是在 Linux 系統上的話,該怎麼執行你要執行的命令呢?其實很簡單,只需要在 crontab 的時間格式後面加上你要執行的命令就可以了,例如:

1
0 9 * * 1-5 node /home/ithelp/ithelp.js

這樣子就可以在每週一到週五的早上九點執行 /home/ithelp/ithelp.js 這個檔案了。

那麼關於 Linux 的部分我就不細講了,畢竟這不是我這一次的主題範圍內。

最後,如果你覺得 crontab 格式很難記的話,其實你可以到 crontab guru 網站上去做測試,這個網站可以幫你解析 crontab 的格式,並且會告訴你這個 crontab 會在什麼時候執行哩~

那麼這一篇也差不多要結束了,剩下的我們下一篇見囉~