Linux 定時任務 crontab 和 Systemd Timer


一、說說八卦

​ 說到定時任務,我們常用的就是 crond 服務,但是我們不知道還有另外一種定時方式,那就是 systemd,我們常用 systemd 來管理我們的服務,但是我們卻不知道,我們還可以通過 systemd 來設置定時任務。本文將記錄下 crond 服務和 systemd服務來設置定時任務。 (at 命令使用較少,在此未記錄)

二 、crond服務

我們常用的定時任務就是 crond 服務,crontabcrond 服務的常用命令,我們經常通過該服務來定時或者周期性幫我們執行一些任務。

crond 服務的一些基本概念

crond 讀取配置文件會從以下幾個路徑讀取:

  • /var/spool/cron/ , 由crontab -e 進行寫入,配置文件無需指定用戶
  • /etc/crontab ,只能root 進行編輯,配置文件需指定用戶
  • /etc/cron.d/ ,在此文件夾下創建定時任務文件,配置文件需指定用戶

crond 服務的常用文件:

  • /var/spool/cron/

  • /etc/crontab

  • /etc/cron.d/

  • /var/log/cron # crond 服務日志位置

  • /etc/cron.deny # 禁止使用 crond 服務的賬號,默認創建的用戶是允許使用 crond 服務的。

    要禁止某個用戶,就直接將該用戶名寫入該文件

crontab 常用命令

# 查看當前的 crontab 任務
crontab -l
# 編輯 crontab 任務,不符合規則的任務會報錯。
crontab -e
# 幫助其他用戶查看/編輯 crontab 任務,只有 root 用戶才可以使用。
crontab -u username -l # 查看
crontab -u username -e # 編輯
# 刪除所有的 crontab 任務
crontab  -r
# crond 服務狀態
systemctl status  crond
# crond 服務啟動/暫停/重啟
systemctl start/stop/reload  crond

**crontab 定時任務基本語法 **

# 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
# |  |  |  |  |
# *  *  *  *  *   command to be executed

字符 含義
* 任何時刻,放在分鍾位置上就表示每分鍾。放在小時位置就表示每小時。
, 分割時段,比如要在3點和6點都執行,就可以寫 3,6
- 表示一個區間,比如要1點到5點的20分都執行任務,20 1-5 * * * command
/n n代表的是數字,表示每隔 n 個時間執行一次。 比如要每2分鍾執行任務,*/2 * * * * command

crontab -e (/var/spool/cron) 配置

crontab -e 命令是會檢查語法的,語法錯誤的話,是會不通過的,crontab -e 保存在 /var/spool/cron 文件夾下,並且是以創建用戶命名的,比如我們root 用戶創建的定時任務就是保存在 ``/var/spool/cron/root`

crontab 使用示例:

以下命令都是通過crontab -e 進行編輯的

  1. 要在每天23點10分和1點10分對數據庫進行備份,數據庫備份腳本為 /opt/scripts/back.sh

    10 23,1 * * * /opt/scripts/back.sh
    
  2. 要在 0點到6點 每隔2小時 對數據庫進行備份,數據庫備份腳本為 /opt/scripts/back.sh

    0 0-6/2 * * * /opt/scripts/back.sh
    

/etc/crontab 配置

/etc/crontab 的語法格式和 crontab -e 大致相同,前者需要指定用戶,后者不需要。

SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root # 指的就是當有 stdout 和 stderr 時,發送mail 給誰,默認是root,我們可以指定我們的e-mail賬號,但是前提要在本地配置好郵件發送賬號
*  *  *  *  * user-name  command to be executed
#示例:25-32/2 * * * * root  /opt/test.sh

/etc/cron.d/ 配置

/etc/cron.d/下創建一個文件,文件配置和/etc/crontab 是一樣的,需要指定用戶。

注意點:

在 Linux 底下的 crontab 會自動的幫我們每分鐘重新讀取一次 /etc/crontab 的例行工作事項,但是某些原因或者是其他的 Unix 系統中,由於 crontab 是讀到記憶體當中的,所以在你修改完 /etc/crontab 之後,可能並不會馬上執行, 這個時候請重新啟動 crond 這個服務吧!『systemctl restart crond』

我們在設置計划任務時需要注意一個問題,就是 如果我們設置了月日,就不要設置星期,這兩者是沖突的,只能同時存在一個。

* 15 * * 1-5 /usr/local/bin/tea_time.sh

該腳本表示,每周一到周五下午3點,3點的每分鍾執行一次腳本 /usr/local/bin/tea_time.sh

三 、systemd 服務

之前對於systemd 具有定時任務的功能還是只有耳聞,並沒有實際操作過,今天進行實際操作了下,發現也不錯的。

systemd 實際是通過定義一個timer單元來創建一個定時任務。它包含了兩大內容,首先定義一個service單元,這個service單元定義了我們想定時執行的任務。然后再定義一個timer單元,通過timer單元定義定時規則去執行之前的service單元。

1. 創建定時腳本

首先我們創建一個腳本叫做 now_time.sh,腳本內容就是輸出當時的時間:

cat <<EOF >/opt/now_time.sh
#!/bin/bash
echo "$(date)" >>/tmp/time_record.log
EOF
chmod 755 /opt/now_time.sh  # 注意一定要更改權限,否則后面會由於沒有執行權限而報錯

2. 創建 Service 單元

然后需要創建一個 Service單元 timerecord

cat <<EOF >/usr/lib/systemd/system/timerecord.service 
[Unit]
Description=now time service

[Service]
ExecStart=/opt/now_time.sh

[Install]
WantedBy=multi-user.target
EOF

然后把 timerecord 作為系統服務。

systemctl start timerecord

**3. 創建 Timer 單元 **

在創建 Timer單元前,我們需要先了解下如何配置 Timer,

[Unit] # 定義元數據
[Timer] #定義定時器
OnActiveSec:定時器生效后,多少時間開始執行任務
OnBootSec:系統啟動后,多少時間開始執行任務
OnStartupSec:Systemd 進程啟動后,多少時間開始執行任務
OnUnitActiveSec:該單元上次執行后,等多少時間再次執行
OnUnitInactiveSec: 定時器上次關閉后多少時間,再次執行
OnCalendar:基於絕對時間,而不是相對時間執行,用於和 crond 類似的定時任務 ,以實際時間執行。
AccuracySec:如果因為各種原因,任務必須推遲執行,推遲的最大秒數,默認是60秒
Unit:真正要執行的任務,默認是同名的帶有.service后綴的單元
Persistent:如果設置了該字段,即使定時器到時沒有啟動,也會自動執行相應的單元
WakeSystem:如果系統休眠,是否自動喚醒系統

示例:

  1. 在系統啟動15分鍾后啟動,並在系統運行時,每周啟動一次。

    [Unit]
    Description=Run foo weekly and on boot
    
    [Timer]
    OnBootSec=15min
    OnUnitActiveSec=1w 
    
    [Install]
    WantedBy=timers.target
    
  2. 每周執行一次(周一凌晨0點)。激活后,如果錯過了上次啟動時間,,它會立即觸發服務,例如由於系統斷電:

    [Unit]
    Description=Run foo weekly
    
    [Timer]
    OnCalendar=weekly
    Persistent=true
    
    [Install]
    WantedBy=timers.target
    
  3. 每天周一下午3點10分運行

    如果需要具體的時間,我們可以給OnCalendar 設定具體時間值,形如 Year-Month-Day Hour:Minute:Second

    [Unit]
    Description=Run timerecord on Monday 3:10
    
    [Timer]
    OnCalendar=Mon *-*-* 15:10:00
    Unit=timerecord
    
    [Install]
    WantedBy=timers.target
    
  4. 每隔5秒執行一次

    [Unit]
    Description=Run timerecord  every 5s
    
    [Timer]
    OnUnitActiveSec=5s # 可以設置為 5m,1h
    Unit=timerecord
    
    [Install]
    WantedBy=timers.target
    
    
  5. 每個小時的每隔10分鍾 進行備份服務

    [Unit]
    Description=backup
    
    [Timer]
    OnCalendar=*-*-* 0/1:0/10:00
    Unit=backup
    
    [Install]
    WantedBy=multi-user.target
    
    

創建 Timer 單元 record:每隔1分鍾執行一次

cat <<EOF > /usr/lib/systemd/system/timerecord.timer
[Unit]
Description=Run timerecord  every 5s

[Timer]
OnUnitActiveSec=1m # 可以設置為 5m,1h
Unit=timerecord #指定 Service 服務名

[Install]
WantedBy=timers.target
EOF

啟用定時任務

systemctl  daemon-reload  #重新加載配置
systemctl  start  timerecord.timer # 啟動定時任務

常用命令:

systemctl  start  timerecord.timer# 啟動定時任務
systemctl  stop  timerecord.timer# 暫停定時任務
systemctl  status  timerecord.timer# 查看定時任務服務狀態
systemctl  restart  timerecord.timer# 重啟定時任務狀態
systemctl list-timers --all # 查看定時任務列表
systemctl  daemon-reload  # 更改了配置文件后,需要重新加載
journalctl -u mytimer.timer # 查看 mytimer.timer 的日志
journalctl -u mytimer # 查看 mytimer.timer 和 mytimer.service 的日志
journalctl -f # 從結尾開始查看最新日志
journalctl -f -u timer.timer #  從結尾開始查看 mytimer.timer 的日志

參考文獻:https://wiki.archlinux.org/index.php/Systemd/Timers

http://www.ruanyifeng.com/blog/2018/03/systemd-timer.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM