Linux 技巧: 用 cron 和 at 調度作業

摘自:http://www.ibm.com/developerworks/cn/linux/l-job-scheduling.html

 Linux® 和 UNIX® 系統允許調度任務在以後執行一次,或者重複運行。本文是從 developerWorks 教程 “LPI 102 考試準備:管理任務” 摘錄的,講解如何調度作業定期運行,或在指定的時間運行一次。

在 Linux 系統上,許多管理任務必須頻繁地定期執行。這些任務包括輪轉日誌文件以避免裝滿文件系統、備份數據和連接時間服務器來執行系統時間同步。上面提到的教程更詳細地介紹了這些管理任務。在本文中,學習 Linux 中提供的調度機制,包括 cronanacron 設施以及 crontabat 命令。即使系統常常關機,anacron 也可以幫助調度作業。

以一定的時間間隔運行作業

以一定的時間間隔運行作業需要使用 cron 設施進行管理,它由 crond 守護進程和一組表(描述執行哪些操作和採用什麼樣的頻率)組成。這個守護進程每分鐘喚醒一次,並通過檢查 crontab 判斷需要做什麼。用戶使用 crontab 命令管理 crontab。crond 守護進程常常是在系統啓動時由 init 進程啓動的。

爲了簡單,假設希望定期運行清單 1 所示的命令。這個命令實際上只報告日期和時間,其他什麼事都不做,但是它可以說明如何使用 crontab 設置 cron 作業,而且還可以通過輸出看到作業運行的時間。設置 crontab 條目需要一個包含轉義的 shell 元字符的字符串,所以適合於簡單的命令和參數。在這個示例中,將從腳本 /home/ian/mycrontab.sh 運行 echo 命令,這個腳本不需要參數。 這可以減少處理轉義字符的工作。


清單 1. 一個簡單的命令示例
                
[ian@lyrebird ~]$ cat mycrontest.sh
#!/bin/bash
 echo "It is now $(date +%T) on $(date +%A)"
[ian@lyrebird ~]$ ./mycrontest.sh
It is now 18:37:42 on Friday

創建 crontab

使用 crontab 命令和 -e(表示 “edit”)選項創建 crontab。這會打開 vi 編輯器,除非在 EDITOR 或 VISUAL 環境變量中指定了另一種編輯器。

每個 crontab 條目包含六個字段:

  1. 分鐘
  2. 小時
  3. 星期
  4. sh 執行的字符串

分鐘和小時的範圍分別是 0-59 和 0-12,日和月的範圍分別是 1-31 和 1-12。星期的範圍是 0-6,0 表示星期日。星期也可以指定爲 sun、mon、tue 等等。第 6 個字段包含前 5 個字段之後的所有內容,它是要傳遞給 sh 的字符串。百分號(%)將轉換爲空行,所以如果要使用 % 或其他任何特殊字符,就要在前面加上反斜線(\)。第一個 % 之前的一行傳遞給 shell,這個 % 之後的所有行都作爲標準輸入傳遞。

各個與時間相關的字段可以指定一個單獨的值、值的範圍(比如 0-10 或 sun-wed)或者以逗號分隔的單獨值和範圍列表。清單 2 給出一個 crontab 條目示例。


清單 2. 一個簡單的 crontab 示例
                
0,20,40 22-23 * 7 fri-sat /home/ian/mycrontest.sh

在這個示例中,我們的命令在 7 月的每個星期五和星期六晚上 10 點到午夜之間的第 0、20、40 分鐘(每 20 分鐘)執行。關於指定時間的其他方式的細節,參見 crontab(5) 的手冊頁。

輸出

您可能想知道對來自命令的輸出會如何處理。爲使用 cron 而設計的大多數命令會使用 syslog 在日誌中記錄輸出(參見教程 “LPI 102 考試準備:管理任務” 中的討論)。但是,定向到 stdout 的輸出會通過電子郵件發送給用戶。清單 3 給出我們的命令示例可能產生的輸出。


清單 3. 通過電子郵件發送的 cron 輸出
                
From [email protected]  Fri Jul  6 23:00:02 2007
Date: Fri, 6 Jul 2007 23:00:01 -0400
From: [email protected] (Cron Daemon)
To: [email protected]
Subject: Cron <ian@lyrebird> /home/ian/mycrontest.sh
Content-Type: text/plain; charset=UTF-8
Auto-Submitted: auto-generated
X-Cron-Env: <SHELL=/bin/sh>
X-Cron-Env: <HOME=/home/ian>
X-Cron-Env: <PATH=/usr/bin:/bin>
X-Cron-Env: <LOGNAME=ian>
X-Cron-Env: <USER=ian>

It is now 23:00:01 on Friday


crontab 存儲在哪裏?

suid 程序

suid 程序以程序文件的所有者的權限運行,而不是採用運行程序的用戶的權限。關於 suid 的更多信息,參見教程 “LPI 101 考試準備:設備、Linux 文件系統和 Filesystem Hierarchy Standard”;關於 passwd 命令的更多信息,參見教程 “LPI 102 考試準備:管理任務”。

crontab 命令創建的 crontab 存儲在 /etc/spool/cron 下面的一個子目錄中,這個子目錄與創建 crontab 的用戶同名,所以上面的 crontab 存儲在 /etc/spool/cron/ian 中。因此,與 passwd 命令一樣,crontab 命令是一個用根權限運行的 suid 程序。

/etc/crontab

除了 /var/spool/cron 中的用戶 crontab 文件之外,cron 還會檢查 /etc/crontab 文件和 /etc/cron.d 目錄中的文件。在這些系統 crontab 中,在第五個時間字段(星期)和命令之間增加了一個字段。這個字段指定哪個用戶應該運行這個命令,一般情況下是根用戶。清單 4 給出一個 /etc/crontab 文件示例。


清單 4. /etc/crontab
                
SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root
HOME=/

# run-parts
01 * * * * root run-parts /etc/cron.hourly
02 4 * * * root run-parts /etc/cron.daily
22 4 * * 0 root run-parts /etc/cron.weekly
42 4 1 * * root run-parts /etc/cron.monthly
      

在這個示例中,真正的工作由 run-parts 命令執行,它運行 /etc/cron.hourly、/etc/cron.daily 等目錄中的腳本;/etc/crontab 僅僅控制執行作業的時間。注意,這裏的所有命令都作爲根用戶運行。還要注意,crontab 可以包含 shell 變量賦值,這些賦值會在運行命令之前執行。

anacron

cron 適合那些連續運行的系統。對於那些常常不開機的系統,比如筆記本計算機,可以使用另一個實用程序 anacron(表示 “anachronistic cron”)調度每日、每週或每月執行的作業。anacron 不處理每小時執行的作業。

anacron 在 /var/spool/anacron 中保留時間戳文件,記錄作業運行的時間。當 anacron 運行時,它檢查自作業上一次運行以來是否已經經過了所需的天數,如果需要,就運行作業。anacron 的作業表存儲在 /etc/anacrontab 中,文件格式與 /etc/crontab 略有不同。與 /etc/crontab 一樣,/etc/anacrontab 可以包含環境設置。每個作業有四個字段:

  1. 週期
  2. 延遲
  3. 作業標識符
  4. 命令

週期是天數,但是可以指定爲 @monthly,這確保作業每個月只運行一次(無論這個月中有多少天)。延遲是在作業符合運行條件之後,到實際啓動它之前等待的分鐘數。可以使用這個設置防止在系統啓動時集中執行作業。作業標識符可以包含除了斜線(/)之外的所有非空白字符。

/etc/crontab 和 /etc/anacrontab 都通過直接編輯進行更新。不使用 crontab 命令更新這些文件或 /etc/cron.d 目錄中的文件。


在指定的時間運行作業

有時候,需要只運行作業一次而不是定期運行。爲此,應該使用 at 命令。要運行的命令是從 -f 選項指定的文件讀取的,如果沒有使用 -f,那麼從 stdin 讀取。-m 選項向用戶發送郵件,即使命令沒有 stdout。-v 選項顯示運行作業的時間。這個時間也顯示在輸出中。

清單 5 給出一個運行 mycrontest.sh 腳本的示例。清單 6 顯示在運行作業之後通過郵件發送給用戶的輸出。注意,這裏的輸出比對應的 cron 作業輸出要簡單一些。


清單 5. 使用 at 命令
                
[ian@lyrebird ~]$ at -f mycrontest.sh -v 10:25
Sat Jul  7 10:25:00 2007

job 5 at Sat Jul  7 10:25:00 2007


清單 6. 來自 at 的作業輸出
                
From [email protected]  Sat Jul  7 10:25:00 2007
Date: Sat, 7 Jul 2007 10:25:00 -0400
From: Ian Shields <[email protected]>
Subject: Output from your job        5
To: [email protected]

It is now 10:25:00 on Saturday


時間的設置可以非常複雜。清單 7 給出幾個示例。參見 at 的手冊頁、/usr/share/doc/at/timespec 文件或 /usr/share/doc/at-3.1.10/timespec 這樣的文件(這個示例中的 3.1.10 是 at 包的版本號)。


清單 7. at 命令使用的時間值
                
[ian@lyrebird ~]$ at -f mycrontest.sh  10pm tomorrow
job 14 at Sun Jul  8 22:00:00 2007
[ian@lyrebird ~]$ at -f mycrontest.sh 2:00 tuesday
job 15 at Tue Jul 10 02:00:00 2007
[ian@lyrebird ~]$ at -f mycrontest.sh 2:00 july 11
job 16 at Wed Jul 11 02:00:00 2007
[ian@lyrebird ~]$ at -f mycrontest.sh 2:00 next week
job 17 at Sat Jul 14 02:00:00 2007

nice 值

nice 值表示一個作業對於其他用戶的優先程度。關於 nicerenice 命令的更多信息,參見教程 “LPI 101 考試準備:GNU 和 UNIX 命令”。

at 命令還有一個 -q 選項。隨着隊列的增長,作業的 nice 值也會增長。 還有一個 batch 命令,它與 at 命令相似,但是作業只在系統負載足夠低時運行。這些特性的細節參見手冊頁。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章