在linux系統中你可能已經發現了爲什麼系統常常會自動的進行一些任務?這些任務到底是誰在支配他們工作的?在linux系統如果你想要讓自己設計的備份程序可以自動在某個時間點開始在系統底下運行,而不需要手動來啓動它,又該如何處置呢? 這些例行的工作可能又分爲一次性定時工作與循環定時工作,在系統內又是哪些服務在負責?
命令at及crontab可以解決上述問題
at:未來的某時間點執行一次某任務
crontab:用於週期性運行某任務
二者的執行結果或通過郵件發送給用戶。
at命令
通過命令yum provides atd查看at的包名
yum provides atd root@localhost Loaded plugins: fastestmirror Loading mirror speeds from cached hostfile base/7/x86_64/filelists_db | 6.7 MB 00:00:00 epel/x86_64/filelists_db | 8.1 MB 00:00:00 extras/7/x86_64/filelists_db | 391 kB 00:00:00 updates/7/x86_64/filelists_db | 1.5 MB 00:00:00 zabbix/x86_64/filelists_db | 53 kB 00:00:00 zabbix-non-supported/x86_64/filelists | 660 B 00:00:00 at-3.1.13-22.el7.x86_64 : Job spooling tools Repo : base Matched from: Filename : /usr/sbin/atd at-3.1.13-22.el7.x86_64 : Job spooling tools Repo : @base Matched from: Filename : /usr/sbin/atd
常用格式:at [option] ... TIME
at允許使用一套相當複雜的指定時間的方法。他能夠接受在當天的hh:mm(小時:分鐘)式的時間指定。假如該時間已過去,那麼就放在第二天執行。當然也能夠使用midnight(深夜),noon(中午),teatime(飲茶時間,一般是下午4點)等比較模糊的 詞語來指定時間。用戶還能夠採用12小時計時制,即在時間後面加上AM(上午)或PM(下午)來說明是上午還是下午。 也能夠指定命令執行的具體日期,指定格式爲month day(月 日)或mm/dd/yy(月/日/年)或dd.mm.yy(日.月.年)。指定的日期必須跟在指定時間的後面。 上面介紹的都是絕對計時法,其實還能夠使用相對計時法,這對於安排不久就要執行的命令是很有好處的。指定格式爲:now + count time-units ,now就是當前時間,time-units是時間單位,這裏能夠是minutes(分鐘)、hours(小時)、days(天)、weeks(星期)。count是時間的數量,究竟是幾天,還是幾小時,等等。 更有一種計時方法就是直接使用today(今天)、tomorrow(明天)來指定完成命令的時間。
TIME:時間格式,這裏可以定義出什麼時候要進行 at 這項任務的時間,格式有:
HH:MM
ex> 04:00
在今日的 HH:MM 時刻進行,若該時刻已超過,則明天的 HH:MM 進行此任務。
HH:MM YYYY-MM-DD
ex> 04:00 2016-09-19
強制規定在某年某月的某一天的特殊時刻進行該項任務
HH:MM[am|pm] [Month] [Date]
ex> 04pm September 17
也是一樣,強制在某年某月某日的某時刻進行該項任務
HH:MM[am|pm] + number [minutes|hours|days|weeks]
ex> now + 5 minutes
ex> 04pm + 3 days
就是說,在某個時間點再加幾個時間後才進行該項任務。
常用選項:
-l:查看作業隊列,相當於atq
-f:從指定文件中讀取作業任務,而不用再交互式輸入
-d:刪除指定的作業,相當於atrm
-c:查看指定作業的具體內容
-q:指明隊列
注:作業執行結果是以郵件發送給提交作業的用戶
在使用at命令前,我們需要先確認at所依賴的atd進程是否啓用,使用命令:ps -ef | grep atd查看,若未啓用則用/etc/init.d/atd start or restart開啓。
執行方式:
1)交互式,在命令輸入完成後使用ctrl+d保存退出;2)輸入重定向;3)at -f 文件
示例1:2分鐘後使用ls命令展開/tmp目錄(交互式命令輸入結束後使用ctrl+d保存退出)
[root@docker ~]# at now + 2 minutes at> ls /tmp at> <EOT> job 7 at Sun Sep 18 09:17:00 2016
命令執行結果在mail裏面看
[root@docker ~]# mail Heirloom Mail version 12.5 7/5/10. Type ? for help. "/var/spool/mail/root": 9 messages 1 unread 1 [email protected] Tue Jul 19 16:46 90/2915 "[abrt] full crash report" 2 [email protected] Thu Sep 8 11:00 16/568 "Output from your job 1" 3 [email protected] Mon Sep 12 10:31 353/15306 "[abrt] full crash report" 4 [email protected] Mon Sep 12 10:31 443/17535 "[abrt] full crash report" 5 root Sun Sep 18 09:04 23/998 "Output from your job 3" 6 root Sun Sep 18 09:08 19/827 "Output from your job 4" 7 root Sun Sep 18 09:13 275/2986 "Output from your job 5" 8 root Sun Sep 18 09:15 26/552 "Output from your job 6" >U 9 root Sun Sep 18 09:17 18/776 "Output from your job 7" >U 9 root Sun Sep 18 09:17 18/776 "Output from your job 7" & 9 Message 9: From [email protected] Sun Sep 18 09:17:01 2016 Return-Path: <[email protected]> X-Original-To: root Delivered-To: [email protected] Subject: Output from your job 7 To: [email protected] Date: Sun, 18 Sep 2016 09:17:01 +0800 (CST) From: [email protected] (root) Status: RO systemd-private-2c8c4ebab1524b5c9f463bd2ec8ffea7-colord.service-gyAadP systemd-private-2c8c4ebab1524b5c9f463bd2ec8ffea7-cups.service-6gB4MM systemd-private-2c8c4ebab1524b5c9f463bd2ec8ffea7-rtkit-daemon.service-25oPVw systemd-private-2c8c4ebab1524b5c9f463bd2ec8ffea7-vmtoolsd.service-sW2CqM
示例2:明天14點中,重啓系統。(使用輸入重定向實現)
[root@docker ~]# at 14:00 tomorrow >> time1 << eof > reboot > eof job 8 at Mon Sep 19 14:00:00 2016 [root@docker ~]# atq 8Mon Sep 19 14:00:00 2016 a root
示例3:刪除示例2的計劃任務
[root@docker ~]# at -d 8 [root@docker ~]# atq
at命令的執行權限:
配置文件/etc/at.{allow,deny}決定了允許哪些用戶可以使用at命令,哪些用戶不可以。
加上這兩個文件後, at 的工作情況是這樣的:
先找尋 /etc/at.allow 這個文件,寫在這個文件中的使用者才能使用 at ,沒有在這個文件中的使用者則不能使用 at (即使沒有寫在 at.deny 當中);
如果 /etc/at.allow 不存在,就尋找 /etc/at.deny 這個文件,若寫在這個 at.deny 的使用者則不能使用 at ,而沒有在這個 at.deny 文件中的使用者,就可以使用 at 命令了。
如果兩個文件都不存在,那麼只有 root 可以使用 at 這個命令。
透過這個說明,我們知道 /etc/at.allow 是管理較爲嚴格的方式,而 /etc/at.deny 則較爲鬆散 (因爲帳號沒有在該文件中,就能夠運行 at 了)。在一般的 distributions 當中,由於假設系統上的所有用戶都是可信任的, 因此係統通常會保留一個空的 /etc/at.deny 文件,意思是允許所有人使用 at 命令的意思 (您可以自行檢查一下該文件)。 不過,萬一你不希望有某些使用者使用 at 的話,將那個使用者的帳號寫入 /etc/at.deny 即可! 一個帳號寫一行。
crontab命令
通過命令yum provides crontab查看crontab命令的包名
yum provides crontab root@localhost Loaded plugins: fastestmirror Loading mirror speeds from cached hostfile cronie-1.4.11-17.el7.x86_64 : Cron daemon for executing programs at set times Repo : base Matched from: Filename : /usr/bin/crontab cronie-1.4.11-14.el7_2.1.x86_64 : Cron daemon for executing programs at set times Repo : @anaconda Matched from: Filename : /usr/bin/crontab
cron來源於希臘單詞chronos(意爲“時間”),是linux系統下一個週期性自動執行指定任務的程序
在使用cron前,需要確認crond守護進程處於運行狀態,才能保證cron的正常運行。
可以通過命令:systemctl status crond 及ps -ef | grep crond查看服務cron是否處於運行狀態。
向crond提交作業的方式與at不同,它需要使用專用的配置文件,此文件有固定格式,不建議使用文本編輯器直接編輯此文件;需要使用crontab命令;
cron任務分爲兩類:
系統cron任務:主要用於實現系統自身的維護
手動編輯/etc/crontab文件
用戶cron任務:使用命令crontab
/etc/crontab文件
注:
1)每一行定義一個週期性任務;共7個字段
* * * * * :定義週期性時間
username:運行任務的用戶身份
command to be executed:要執行的任務
2)此處的環境變量不同於用戶登陸後獲得的環境,因此建議命令使用絕對路徑,或定義PATH環境變量
3)執行結果郵件發送給MAILTO指定的用戶(發送給運行任務的用戶)
時間表示法:
(1) 特定值;
給定時間點有效取值範圍內的值;
(2) *
給定時間點上有效取值範圍內的所有值;
表示“每...”;
示例:
1> 3 * * * * :每小時的第三分鐘執行一次
2> 3 4 * * 5 :每週的週五4:03執行一次
3> 5 6 7 * * :每月的7號6:05執行一次
4> 7 8 9 10 * :每年10月9號8點7分執行一次
(3) 離散取值:在時間上使用逗號分隔的多個值:#,#,#
示例:
5> 9 8 * * 3,7 :每週三週日的8點9分執行一次
6> 0 8,20 * * 3,7 :每週三週日的8:00跟20:00執行一次
(4) 連續取值:在時間點上使用-鏈接開頭和結束:#-#
示例:
7> 0 9-18 * * 1-5 :從週一到週五的9點到18點每小時執行一次
(5) 在指定時間範圍上,定義步長:
/#: #即爲步長
注:1)指定時間點不能被步長整除時,其意義將不復存在:
2)最小時間單位爲“分鐘”,想完成“秒”級任務,需要藉助於其他機制:定義成每分鐘任務,而在利用腳本實現的每分鐘之內循環多次
用戶cron
crontab命令定義,每個用戶都有專用的cron任務文件:/var/spool/cron/USERNAME
只有該用戶定義了cron任務才能通過該文件看到相應信息。
注:1)每行定義一個cron任務,共6個字段(不需要指定用戶);2)郵件發送給當前用戶
crontab命令
使用格式:
crontab [-u user] [-l | -r | -e] [-i]
-l: 列出所有任務;
-e: 編輯任務;
-r: 移除所有任務;
-i:同-r一同使用,以交互式模式讓用戶有選擇地移除指定任務;
-u user: 僅root可運行,代爲爲指定用戶管理cron任務;
注意:運行結果以郵件通知給相關用戶;如果不想接收郵件則可使用如下命令實現
(1) COMMAND > /dev/null
(2) COMMAND &> /dev/null
思考:
(1) 如何在秒級別運行任務?
* * * * * for min in 0 1 2; do echo "hi"; sleep 20; done
(2) 如何實現每7分鐘運行一次任務?
sleep命令:
sleep NUMBER[SUFFIX]...
SUFFIX:
s: 秒, 默認
m: 分
h: 小時
d: 天
練習:
1、每4小時備份一次/etc目錄至/backup目錄中,保存的文件名稱格式爲“etc-yyyy-mm-dd-HH.tar.xz”;
在/etc/crontab文件中添加如下:
0 4 * * * ./test/bak_etc cat bak_etc #!/bin/bash #bakup /etc diratory #auther chawan date:20160908 cp /etc/* /bakup/etc$(date +%F-%H) xz /bakup/etc$(date +%F-%H)
2、每週2, 4, 7備份/var/log/messages文件至/logs目錄中,文件名形如“messages-yyyymmdd”;
* * * * 2,4,7 ./test/logs
cat /test/logs #!/bin/bash #bakup /var/log/messages to /logs cp /var/log/messages /logs/messages$(date +%F) xz /logs/messages$(date +%F)
3、每兩小時取出當前系統/proc/meminfo文件中以S或M開頭的信息追加至/tmp/meminfo.txt文件中;
0 2 * * * cat /proc/meminfo | grep "^[SM]" >> /tmp/meminfo.txt
4、工作日時間內,對用戶docker每小執行一次“ip addr show”命令;
切換至docker用戶使用命令crontab -e進入編輯界面
加入"0 9-18 * * 1-5 docker ip addr show"信息後保存退出
[docker@docker ~]$ crontab -l 0 9-18 * * 1-5 ip addr show