天天看點

Linux-任務計劃Crontab

作者:不寐旋律

#頭條創作挑戰賽#

1 任務計劃

任務計劃是指在Linux系統中定期執行指定的指令、腳本或程式的功能。它可以用于定時備份資料、定時運作腳本、定時清理日志等各種自動化任務。

Linux-任務計劃Crontab

通過任務計劃,可以讓系統自動的按時間或周期性任務執行任務

注意: 學習本節需要實作郵件通知,學習内容前必須安裝并啟動郵件服務

環境準備:

[root@centos8 ~]#yum -y install postfix
[root@centos8 ~]#systemctl enable --now postfix           

未來的某時間點執行一次任務

  • at 指定時間點,執行一次性任務
  • batch 系統自行選擇空閑時間去執行此處指定的任務
  • 周期性運作某任務cron
Linux-任務計劃Crontab

1.1 一次性任務

at 工具

  • 由包 at 提供
  • 依賴于atd服務,需要啟動才能實作at任務
  • at隊列存放在/var/spool/at目錄中
  • 執行任務時PATH變量的值和目前定義任務的使用者身份一緻

at 指令:

at [option] TIME           

常用選項:

-V 顯示版本資訊
-t time 時間格式 [[CC]YY]MMDDhhmm[.ss]
-l 列出指定隊列中等待運作的作業;相當于atq
-d N 删除指定的N号作業;相當于atrm
-c N 檢視具體作業N号任務
-f file 指定的檔案中讀取任務
-m 當任務被完成之後,将給使用者發送郵件,即使沒有标準輸出           

注意:

  • 作業執行指令的結果中的标準輸出和錯誤以執行任務的使用者身份發郵件通知給 root
  • 預設CentOS 8 最小化安裝沒有安裝郵件服務,需要自行安裝(開頭已做好準備)

TIME:定義出什麼時候進行 at 這項任務的時間

HH:MM [YYYY-mm-dd]
noon, midnight, teatime(4pm),tomorrow
now+#{minutes,hours,days, OR weeks}           

案例:at 時間格式

#HH:MM 在今日的 HH:MM 進行,若該時刻已過,則明天此時執行任務
02:00

#HH:MM YYYY-MM-DD 規定在某年某月的某一天的特殊時刻進行該項任務
02:00 2024-09-20

#HH:MM[am|pm] [Month] [Date]
06pm March 17
17:20 tomorrow

#HH:MM[am|pm] + number [minutes|hours|days|weeks], 在某個時間點再加幾個時間後才進行該項任務
now + 5 min
02pm + 3 days           

at 任務執行方式:

  • 互動式
  • 輸入重定向
  • at -f file

/etc/at.{allow,deny} 控制使用者是否能執行at任務

  • 白名單:/etc/at.allow 預設不存在,隻有該檔案中的使用者才能執行at指令
  • 黑名單:/etc/at.deny 預設存在,拒絕該檔案中使用者執行at指令,而沒有在at.deny 檔案中的使用者則可執行
  • 如果兩個檔案都不存在,隻有 root 可以執行 at 指令

1.2 周期性任務計劃 cron

Linux-任務計劃Crontab

周期性任務計劃cron相關的程式包:

  • cronie:主程式包,提供crond守護程序及相關輔助工具
  • crontabs:包含CentOS提供系統維護任務
  • cronie-anacron:cronie的補充程式,用于監控cronie任務執行狀況,如:cronie中的任務在過去該運作的時間點未能正常運作,則anacron會随後啟動一次此任務

cron 依賴于crond服務,確定crond守護處于運作狀态:

#CentOS 7 以後版本:
systemctl status crond

#CentOS 6:
service crond status           

cron任務分為:

  • 系統cron任務:系統維護作業,/etc/crontab 主配置檔案, /etc/cron.d/ 子配置檔案
  • 使用者cron任務:儲存在 /var/spool/cron/USERNAME,利用 crontab 指令管理

計劃任務日志:/var/log/cron

1.2.1 系統cron計劃任務

/etc/crontab 格式說明,詳情參見 man 5 crontab

注釋行以 # 開頭

[root@centos8 ~]#cat /etc/crontab
SHELL=/bin/bash  #預設的SHELL類型
PATH=/sbin:/bin:/usr/sbin:/usr/bin  #預設的PATH變量值,可修改為其它路徑
MAILTO=root  #預設标準輸出和錯誤發郵件給root,可以指向其它使用者
 
# For details see man 4 crontabs
 
# 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
# | | | | |
# * * * * * user-name command to be executed           

計劃任務時間表示法:

(1) 特定值
給定時間點有效取值範圍内的值

(2) *
給定時間點上有效取值範圍内的所有值,表示“每...”,放在星期的位置表示不确定

(3) 離散取值
#,#,#
  
(4) 連續取值
#-#
  
(5) 在指定時間範圍上,定義步長
/#: #即為步長

(6) 特定關健字
@yearly 0 0 1 1 *
@annually 0 0 1 1 *
@monthly 0 0 1 * *
@weekly 0 0 * * 0
@daily 0 0 * * *
@hourly 0 * * * *
@reboot Run once after reboot           

幫助:

[root@centos8 ~]#man 5 crontab
For example, "0-23/2" can be used in the 'hours' field to specify command
execution for every other hour (the alternative in the V7 standard is
"0,2,4,6,8,10,12,14,16,18,20,22")           

案例:

#晚上9點10分運作echo指令,輸出資訊仍會發送到root 郵箱
10 21 * * * wang /bin/echo "Howdy!"

#每3小時echo和wall指令
0 */3 * * * wang /bin/echo “howdy”; wall “welcome to Magedu!”           

crond任務相關檔案:

/etc/crontab 配置檔案
/etc/cron.d/ 配置檔案
/etc/cron.hourly/ 腳本
/etc/cron.daily/ 腳本
/etc/cron.weekly/ 腳本
/etc/cron.monthly/ 腳本           

1.2.2 anacron

運作計算機關機時cron不運作的任務,CentOS6以後版本取消anacron服務,由crond服務管理,對筆記本電腦、桌上型電腦、工作站、偶爾要關機的伺服器及其它不一直開機的系統很重要對很有用。

由/etc/cron.hourly/0anacron執行,當執行任務時,更新/var/spool/anacron/cron.daily 檔案的時間戳

配置檔案:/etc/anacrontab,負責執行/etc/ cron.daily /etc/cron.weekly /etc/cron.monthly中系統任務

/etc/anacrontab格式說明:

  • 字段1:如果在這些日子裡沒有運作這些任務……
  • 字段2:在重新開機後等待這麼多分鐘後運作它
  • 字段3:任務識别器,在日志檔案中辨別
  • 字段4:要執行的任務
Linux-任務計劃Crontab

1.2.3 管理臨時檔案

  • CentOS 7 使用 systemd-tmpfiles-setup服務實作
  • CentOS 6 使用/etc/cron.daily/tmpwatch定時清除臨時檔案

配置檔案:

/etc/tmpfiles.d/*.conf
/run/tmpfiles.d/*.conf
/usr/lib/tmpfiles/*.conf           

/usr/lib/tmpfiles.d/tmp.conf

d /tmp 1777 root root 10d
d /var/tmp 1777 root root 30d           

指令:

systemd-tmpfiles –clean|remove|create configfile           

1.2.4 使用者計劃任務

crontab指令:

  • 每個使用者都有專用的cron任務檔案:/var/spool/cron/USERNAME
  • 預設标準輸出和錯誤會被發郵件給對應的使用者,如:wang建立的任務就發送至wang的郵箱
  • root能夠修改其它使用者的作業
  • 使用者的cron 中預設 PATH=/usr/bin:/bin,如果使用其它路徑,在任務檔案的第一行加PATH=/path或者加入到計劃任務執行的腳本中
  • 第六個字段指定要運作的指令。 該行的整個指令部分,直至換行符或“%”字元,指定的shell執行.除非使用反斜杠(\)進行轉義,否則該指令中的“%”字元将變為換行符,并且第一個%之後的所有資料将作為标準輸入發送到該指令。
Linux-任務計劃Crontab

crontab指令格式:

crontab [-u user] [-l | -r | -e] [-i]           

常用選項:

-l 列出所有任務
-e 編輯任務
-r 移除所有任務
-i 同-r一同使用,以互動式模式移除指定任務
-u user 指定使用者管理cron任務,僅root可運作           

控制使用者執行計劃任務:

/etc/cron.{allow,deny}

案例:修改預設的cron的文本編輯工具

root@ubuntu1804:~# crontab -e
no crontab for root - using an empty one
Select an editor. To change later, run 'select-editor'.
1. /bin/nano <---- easiest
2. /usr/bin/vim.basic
3. /usr/bin/vim.tiny
4. /bin/ed
Choose 1-4 [1]:

root@ubuntu1804:~# cat /etc/profile.d/env.sh
export EDITOR=vim           

案例:PATH變量

#方法1,在計劃任務配置中指定PATH
[root@centos8 ~]#crontab -l
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
* * * * * useradd hehe;echo $PATH
 
#方法2,在腳本中指定PATH變量
[root@centos8 ~]#crontab -l
* * * * * /data/test.sh

[root@centos8 ~]#cat /data/test.sh
#!/bin/bash
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
useradd hehe
echo $PATH           

示例:

[root@centos8 ~]#cat /usr/bin/disk_check.sh
#!/bin/bash

WARNING=10
df | sed -En '/^\/dev\/sd/s@^([^ ]+).* ([0-9]+)%.*@\1 \2@p'| while read DEVICE
USE;do
[ $USE -gt $WARNING ] && echo "$DEVICE will be full,USE:$USE" | mail -s
diskfull root
done
[root@centos8 ~]#crontab -l
*/10 * * * * check_disk.sh           

示例:

[root@centos8 ~]#cat check_disk.sh
#!/bin/bash

df | awk -F ' +|%' '/^\/dev\/sd/{if($5 > 10){system("echo "$1" will be
full,use:" $5 "| mail -s warning  [email protected](你的郵箱)")} }'

[root@centos8 ~]#crontab -l
*/10 * * * * /root/check_disk.sh           

示例:1月每天的6-12點之間每隔2小時執行/app/bin/test.sh

[root@centos8 ~]#crontab -l
0 6-12/2 * 11 * /app/bin/test.sh           
Linux-任務計劃Crontab

注意:運作結果的标準輸出和錯誤以郵件通知給相關使用者

(1) COMMAND > /dev/null
(2) COMMAND &> /dev/null           

cron任務中不建議使用%,它有特殊用途,它表示換行的特殊意義,且第一個%後的所有字元串會被将成當作指令的标準輸入,如果在指令中要使用%,則需要用 \ 轉義

注意:将%放置于單引号中是不支援的

示例: 在crontab中%的用法

30 2 * * * /bin/cp -a /etc/ /data/etc`date +\%F_\%T`
30 2 * * * /bin/cp -a /etc/ /data/etc`date +‘%F_%T’` 有問題           

(1) 如何在秒級别運作任務?

for min in 0 1 2; do echo "hi"; sleep 20; done           

(2) 如何實作每7分鐘運作一次任務?

sleep指令:

sleep NUMBER[SUFFIX]...
SUFFIX:
s: 秒, 預設
m: 分
h: 小時
d: 天           

案例:

[root@centos8 ~]#usleep
warning: usleep is deprecated, and will be removed in near future!
warning: use "sleep 1e-06" instead...           
[root@centos8 ~]#time usleep 1000000
warning: usleep is deprecated, and will be removed in near future!
warning: use "sleep 1" instead...
real 0m1.001s
user 0m0.001s
sys 0m0.000s
You have new mail in /var/spool/mail/root
 
[root@centos8 ~]#time ls
all.sh anaconda-ks2.cfg at.txt scanhost.sh
real 0m0.004s
user 0m0.001s
sys 0m0.003s

[root@centos8 ~]#time sleep 0.2
real 0m0.202s
user 0m0.001s
sys 0m0.000s           
Linux-任務計劃Crontab

繼續閱讀