cron 定時執行詳解

linux cron 下的定時執行工具使用技巧

來源:互聯網 作者:佚名 時間:04-13 11:18:03   
點評:cron是一個linux下的定時執行工具,可以在無需人工干預的情況下運行作業。由於Cron 是Linux的內置服務,但它不自動起來,可以用以下的方法啓動、關閉這個服務: /sbin/service crond start //啓動服務 /sbin/service crond stop //關閉服務 /sbin/service crond restart /

瞭解 cron 概念  cron 守護進程是一個由實用程序和配置文件組成的小型子系統,在幾乎所有類 UNIX 系統上都可以找到某種風格的 cron。cron 的組件包括守護進程本身;一組系統範圍的配置文件;一組針對特定用戶的配置文件;一個用來添加、修改和刪除用戶配置文件的實用程序;以及一個簡單的訪問控制設施。一般來說,cron 配置文件或 cron 作業的列表被稱爲 crontab 或 cron 時間表。守護進程 cron 連續運行,每分鐘檢查一次配置文件中的修改。cron 讀取系統範圍的和針對用戶的 crontab(分別在下面兩段中詳細說明)、相應地更新事件調度計劃並執行這一分鐘內應該執行的所有命令。這個守護進程還捕捉每個作業的輸出(如果有輸出的話),並把結果通過電子郵件發送給作業的所有者。

  可以在三個位置定義與系統相關的 作業:/etc/crontab、/etc/cron.d 中的任何文件以及特殊目錄 /etc/cron.hourly、/etc/cron.daily、/etc/cron.weekly 和 /etc/cron.monthly:

  主要的系統 crontab 是/etc/crontab。這個文件有獨特的語法(在下一節中討論),其中定義的每個作業根據它自己的時間表(比如每小時兩次或每天一次)作爲指定的用戶運行。使用 /etc/crontab 調度各種管理和維護任務。

  還可以在 /etc/cron.d 目錄中維護一組 crontab。通過創建 crontab,按照邏輯對屬於某一子系統的命令進行分組。例如,PHP 5 編程語言的包在 /etc/cron.d 中安裝一個名爲 php5 的 crontab,它會定期清除不使用的會話。/etc/cron.d 中的文件採用與 /etc/crontab 相同的語法,每個作業按照自己的時間表並作爲特定的用戶運行。

  還可以把 shell 腳本直接放在 /etc/cron.hourly、/etc/cron.daily、/etc/cron.weekly 或 /etc/cron.monthly 目錄中,這樣就可以每小時、每天、每週或每月運行此腳本一次。放在這裏的腳本作爲超級用戶運行。

  針對用戶的 crontab 集合通常放在 /var/spool/cron/crontabs 中。(具體位置請參見您的 UNIX 系統文檔。一些系統把用戶 crontab 放在 /usr/lib 中)。但是,不能直接編輯此目錄中的文件,而是使用 crontab 實用程序創建 crontab 並提交文件。稍後討論如何管理個人的 crontab。

  最後,可以分別使用訪問控制文件 /etc/cron.allow 和 /etc/cron.deny 允許或拒絕用戶訪問 cron。例如,如果某個用戶的作業可能會破壞系統的正常操作,就可以拒絕他訪問 cron。

  如您所見,不需要爲保持系統不間斷運行而犧牲您的休息時間。只需確定作業、定義它的調度計劃並在適當的 crontab 中設置此作業,然後就可以放心地休息了。現在就來看看 cron 文件的特殊語法。

  處理 crontab

  crontab 僅僅是一個文本文件,可以用任何 UNIX 編輯器編輯它。它可以包含四種代碼行:空行、註釋、環境變量設置和命令。

  空行和註釋

  文件中的空行和多餘的空格被忽略。空行和空格有助於提高 crontab 的可讀性,使 crontab 組織有序。

  還可以使用註釋對每個作業的時間表和用途加以說明。要想創建註釋,只需在一行的開頭加上一個井號(#)。

  環境變量和命令

  cron 最終使用一個 shell 執行每個命令。可以通過環境變量修改或定製 shell 的行爲。

  在 crontab 中很容易設置 shell 環境變量。只需輸入 VARIABLE=value,把 VARIABLE 替換爲變量名,把 value 替換爲一個值。例如,crontab 行:

PATH=/usr/bin:/bin:/usr/local/bin

  指定一個有序的目錄列表作爲 shell 搜索路徑。

  cron 預定義了五個環境變量:

  PATH 的默認值是 /usr/bin:/bin。

  SHELL 預設置爲 /bin/sh。

  LOGNAME 初始化爲 crontab 所有者的用戶名。

  HOME 設置爲 crontab 所有者的主目錄,比如 /home/joe。

  MAILTO 設置爲 crontab 所有者的名稱。

  要想修改這些默認值或設置任何變量,只需在 crontab 中設置適當的環境變量。

  當然,crontab 可以包含任意數量的命令行。每個命令行指定一個頻率、一個用戶名(只對於系統 crontab)和一個要運行的任務。例如,命令:

5 0 * * *  root  find /tmp -type f -empty -delete

  在每天 12:05 a.m(5 0 * * *)刪除 /tmp 中的所有空文件和目錄(find /tmp -type f -empty -delete)。此作業作爲根用戶(root)運行。

  系統 crontab 命令必須指定一個用戶名,作爲運行此任務所用的用戶。(因此,在 /etc/crontab 中可能看到上面的命令)。針對用戶的 crontab 不能指定用戶名;一個用戶的 cron 命令總是作爲這個用戶運行。是否有用戶名是系統 crontab 和用戶 crontab 之間的惟一差異。

  下面討論定製時間表的衆多方式。

  定製時間表

  cron 時間表允許以多種方式運行作業,比如每分鐘或在特定日期的特定時間。調度的參數非常靈活。

  cron 字段

  可以通過五個字段調整頻率:分、小時、月中日、月份和週中的日期(如週一,週二)。表 1 總結如何調整每個字段。

  表 1. cron 作業的調度選項

 

位置 字段 說明
1 0-59  
2 小時 0-23  
3 月中日 1-31 與分和小時不同,月中日不是從零開始的。
4 月份 1-12 月份也不是從零開始的。也可以不使用 1-12 的數字,而是使用月份名的前三個字母,比如 jan 或 may。
5 週中日 0-7 0 和 7 都代表星期日。還可以使用名稱的前三個字母,比如 mon 或 wed。

  除了名稱或數字之外,還可以使用星號(*)表示 “所有”。例如,在分鐘位置上的星號表示這一天中的每一分鐘。(在某些情況下確實需要如此高的頻率,但是一定要小心,以這種頻率執行的任務應該非常簡單,不會長時間運行)。

  還可以使用值的列表、範圍和步長(增量)分別指定多個值、連續的值範圍和不連續的值範圍。甚至可以組合使用列表和範圍。列表 是一個逗號分隔的值集。範圍 由啓始值和結束值(含)以及可選的步長值構成。

  我們來看一些示例。表 2 中的每一行包含一個時間表及其說明。當分、小時和日期字段與當前時間匹配時,cron 會執行命令;如果月中日和週中日受到限制(也就是說,不是 *),那麼當這兩個字段中至少一個 與當前時間匹配時,cron 也會執行命令。

  表 2. cron 作業的時間表示例

 

調度計劃  
小時 月中日 月份 週中日期 說明
0 1 15 1,3,5,7,9,11 * 在 1、3、5、7、9 和 11 月的 15 日的 1 a.m. 運行命令。爲了更容易理解,也可以把這個時間表寫成 0 1 15 jan,mar,may,jul,sep,nov *。在指定列表時,不要在逗號後面加空格。
0-59/15 * * * * 這個調度計劃每 15 分鐘運行命令一次。
30 * * * wed,fri 這個時間表只在星期三和星期五每小時的 30 分時執行命令一次。(在列表中可以使用日和月份的名稱,但是在範圍中不可以)。
0,30 0-5,17-23 * * * 在午夜到 5 a.m. 以及 7 p.m. 到 11 p.m. 之間整點時和 30 分時運行命令。
0 0 1 1 * 在每年 1 月 1 日午夜執行命令一次。
0 0 * * 0 在每個星期日午夜運行命令。這相當於每週一次。
30 0 10,20,30 * 6 因爲月中日和週中日受到限制,這個時間表在每星期六和每月的 10、20 和 30 日(二月除外)的 12:30 a.m. 運行命令。

  如您所見,實際上可以使用這五個參數指定任何調度計劃。爲了更加簡便,Vixie cron 還提供了常用調度計劃的簡寫形式。表 3 列出一些簡寫形式。

  表 3. 常用調度計劃的簡寫形式

 

簡寫形式 說明
@reboot 每當計算機重新引導時運行命令。
@daily 每天一次的簡寫形式。
@weekly 每週一次的簡寫形式。
@annually 每年一次的簡寫形式。也可以寫成 @yearly。
@midnight 在每天午夜運行命令。這個簡寫形式相當於 @daily。

  如果喜歡使用簡寫形式,只需用它們替代 cron 命令的前五個字段。下面這個命令看起來簡單多了。

@daily root /usr/local/scripts/clean_old_files.sh

  crontab 命令示例

  掌握了基本概念之後,我們來看一些用戶 crontab 命令示例。同樣的命令也可以應用系統範圍:只需在所有系統 crontab 項中週中日字段(第五個字段)後面指定一個用戶名。

  創建個人 crontab

  要想創建個人 crontab,可以用任何文本編輯器創建一個文件。按照慣例,個人 crontab 文件保存在 ~/.crontab 中,但是可以使用任何文件名。

PATH=/usr/bin:/bin:/usr/local/bin
#
# Every day, print and delete all temporary files whose names begin with '.#'
@daily   find $HOME -type f -name '.#*' -print -delete
  
#
# Every week, show me what is consuming space in my home directory
@weekly   du -sh $HOME

  通過 crontab 實用程序提交個人 crontab

  在編輯文件(比如 ~/mycrontab)之後,通過 crontab 實用程序把它提交給 cron:

% crontab ~/mycrontab

  查看 cron 中存儲的信息

  要想查看 cron 中存儲的信息,可以輸入 crontab -l:

% crontab -l
PATH=/usr/bin:/bin:/usr/local/bin
  
#
# Every day, print and delete all temporary files whose names begin with '.#'
@daily   find $HOME -type f -name '.#*' -print -delete
#
# Every week, show me what is consuming space in my home directory
@weekly   du -sh $HOME

  替換 crontab

  在任何時候,都可以使用 crontab 實用程序替換您的 crontab。只需提交一個新文件或同一文件的修訂版。要想刪除 crontab 作業,只需輸入 crontab -r:

% whoami
joe
% crontab ~/mycrontab
% crontab -l
PATH=/usr/bin:/bin:/usr/local/bin
...
% crontab -r
% crontab -l
crontab: no crontab for joe

  替代 cron 的機制

  儘管 cron 確實很有用,但是您還應該瞭解可以替代它的兩種機制。

  anacron

  如果系統常常關機或進入休眠狀態(例如,如果使用 UNIX 筆記本計算機的話),那麼可以考慮在系統中添加 anacron。anacron 與 cron 的相似之處在於,它也把作業安排在以後運行;但是,與 cron 不同,即使作業的預定運行時間已經過了,anacron 也會運行作業。

  例如,如果安排在星期六運行文件系統備份,但是系統在星期五到星期一關機了,那麼當系統在星期一重新啓動時,anacron 會立即運行星期六的作業。與之相反,cron 僅僅檢查現在是否應該運行作業;因此,如果在作業的預定運行時間系統是關閉的,就不運行作業。

  anacron 的調度選項比 cron 少得多。它只能以整天的時間間隔調度作業,比如一天、7 天或 30 天;但是對於那些必須頻繁且可靠地運行的作業,它是更好的選擇。

  另外,必須從 cron 啓動 anacron。每當 anacron 運行時,它讀取自己的配置文件。配置文件包含由作業及其頻率(用天數表示)組成的配置對。如果作業在預定的時間沒有運行,anacron 就運行此作業並記錄運行作業的時間。運行完所有作業之後,anacron 退出。

  在大多數 Linux 發行版上都可以找到 anacron,但是也很容易自己下載並構建源代碼。訪問 anacron 項目頁面 獲得最新版本。

  anacron 的主要配置文件可以在 /etc/anacron 中找到。可以像配置 cron 時那樣設置環境變量,但是更簡單:

SHELL=/bin/zsh
PATH=/usr/bin:/bin:/usr/local/bin
# format: frequency delay name job
1 10 day-to-day daily.chores.sh

  第一個數字是週期,所以 1 表示每天運行一次,7 表示每 7 天運行一次,等等。第二個數字是延遲,也就是從 anacron 啓動之後到執行這個作業之間等待的分鐘數。如果把延遲字段設置爲不同的值,就可以防止所有作業同時啓動。名稱 day-to-day 只是一個有幫助的暱稱。配置行的其餘部分指定作業;在這裏,每天運行在指定路徑中找到的 shell 腳本 daily.chores.sh 一次。

  anacron 以手冊頁形式提供了出色的文檔,還可以在網上找到關於 anacron 的提示。(請閱讀我在 2007 年 10 月編輯的 Rod Smith 撰寫的 Linux Magazine 文章)。anacron 適合 UNIX 愛好者和需要額外保障的系統管理員使用。

  launchd:cron 的現代替代機制

  cron 確實是一種功能強大、值得信賴的實用程序,它的廣泛流行就證明了這一點。Vixie cron 最近又有所改進,比如增加了簡寫方式 @reboot,進一步簡化了管理。但是,cron 仍然有一些缺點:

  儘管可以在 crontab 文件中定義 cron 作業,但是不能從命令行啓動和停止 cron 作業。另外,不能在命令行上創建專用作業並提交給日曆。

  cron 不實施資源限制。如果作業作爲根用戶運行,就能夠消耗無數的處理器時間和內存。在實踐中,可能希望限制一個作業,以免它影響其他 cron 作業和系統操作的總體質量。

  cron 作業嚴格地與一個調度計劃相關聯。例如,無法只在發生某一事件(比如創建一個文件)時啓動作業。

  從更大的範疇來看,類 UNIX 系統的許多核心組件都能夠根據需要啓動其他程序,包括 cron、用於網絡守護進程的 xinetd(或 inetd)和 init(所有系統進程的起源)。每個核心組件都有自己的配置文件,所以很難知道哪個組件最適合完成某個修改。

  爲了克服這些缺點,Apple Computer 開發了一個統一的啓動工具 launchd,它可以在引導時、根據需要和按照指定的時間間隔啓動進程。實際上,在 Mac OS 10.4 Tiger 中 launchd 已經替代了 cron(和 init 以及用來引導和初始化系統的其他幾個系統實用程序)。(Apple 在系統上保留了 cron,以便爲用戶提供方便,而且 Vixie cron 的調度選項更靈活)。Mac OS X 的引導速度很快確實可以歸功於 launchd:它會在引導時列出要啓動的程序,但是隻在首次需要時執行程序。

  launchd 是開放源碼的,可以從 Mac OS Forge 上它的主頁獲得源代碼。目前,launchd 已經被移植到 FreeBSD 上,但是還沒有移植到其他 UNIX 或 Linux 系統。但是,許多項目正在積極地實現與 launchd 等效的程序,所以簡要地瞭解它的特性是有必要的:

  launchd 並不創建作業來檢查目錄中是否有新文件,而是自動監視目錄中是否有新文件或者監視空目錄中是否添加了任何文件,並根據需要啓動作業。launchd 不執行輪詢;而是使用 kqueues 設施讓內核在目錄發生變化時通知它。(Linux 具有一種相似的事件設施 inotify,以後的一篇 developerWorks 文章將討論它) 。

  如果指定了,launchd 會使用 chroot 把您的作業發送到一個新目錄。chroot 讀作 “cha-root”,它是一個系統調用,可以改變前向斜槓(/)和根目錄指向的目錄。因此,如果使用 chroot 把文件發送到 /opt/root,/opt/root 之外的所有文件就是不可訪問的(畢竟,/opt/root 現在是 /,也就是文件系統的頂級目錄),/opt/root 中的所有目錄成爲一級目錄。通常使用 chroot 限制作業,使代碼無法進入更大的文件系統,以避免產生損害。

  可以爲作業設置資源限制。可以限制的資源包括內存、堆棧大小和打開的文件的最大數量。

  當定義一個任務並把它裝載到 launchd 中之後,可以按照名稱從命令行啓動和停止作業。

  launchd 由三個組件組成:launchd 守護進程本身;用來添加、修改和刪除作業以及控制 launchd 的 launchctl 實用程序;一個或多個配置文件,每個文件定義一個或多個作業。由於它起源於 Mac OS X,launchd 配置文件只是簡單的屬性文件,可以用 Extensible Markup Language (XML) 表示。

  簡單地說,在 Mac OS X 上使用 launchd 的步驟如下(要監視一個目錄中添加的文件並根據需要運行作業):

  創建一個屬性文件來表達此作業及其所有屬性。

  可以使用 Mac 的 Property Editor,也可以手工編輯 XML。無論採用哪種方法,產生的文件都應該與 清單 1 相似。

  清單 1. 監視文件系統目錄變化的 launchd 作業示例

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST
      1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
  <key>Label</key>
  <string>com.example.processor</string>
  <key>OnDemand</key>
  <true/>
  <key>Program</key>
  <string>/Users/strike/bin/processor</string>
  <key>ProgramArguments</key>
  <array>
    <string>processor</string>
  </array>
  <key>WatchPaths</key>
  <array>
    <string>/Users/strike/data/incoming</string>
  </array>
</dict>
</plist>

  簡單地說,當 /Users/strike/data/incoming 目錄的內容發生變化時,此文件運行 /Users/strike/bin/processor 中的實用程序腳本。把 OnDemand 設置爲 True 讓 launchd 根據需要啓動此作業。把此文件保存到 ~/Library/LaunchAgents/com.example.processor.plist。

  用 launchctl 把此作業裝載到 launchd 中:% launchctl load ~/Library/LaunchAgents/com.example.processor.plist

  如果希望檢查最近的操作或查看保存的作業的列表,只需輸入 launchctl list。

  要想刪除作業,只需帶 unload 選項使用 launchctl:% launchctl unload -w ~/Library/LaunchAgents/com.example.processor.plist

  -w 的作用是什麼?它完全刪除 launchd 中的作業。如果沒有這個選項,作業會在登錄時自動地重新裝載(因爲作業還在啓動代理的用戶集合中)。

  launchd 手冊頁包含大量信息;如果您是 Mac OS X 用戶,還可以找到大量針對 launchd 的應用程序。一些聰明的開發人員正在把 launchd 遷移到更廣泛的平臺。

  使用 cron 讓工作更輕鬆

  學習關於使用 cron 的一些提示和技巧,瞭解這個守護進程和相似的其他程序爲什麼是您的好朋友。

  提示和技巧

  下面是關於 cron 的一些提示、技巧和常見的問題:

  與在終端窗口中使用的 shell 或 shell 腳本不同,cron 並不 在 crontab 文件中就地展開環境變量。換句話說,如果在 crontab 中輸入:HOME=/home/joe
PATH=$HOME/bin:/usr/bin:/bin

  那麼 PATH 並不會設置爲您期望的路徑。您必須手工展開所有變量,比如:

HOME=/home/joe
PATH=/home/joe/bin:/usr/bin:/bin

  但是,因爲每個 cron 命令都由 shell 執行,所以命令可以 引用變量名。例如,如果在個人 crontab 中編寫以下命令(注意這一行中省略了用戶名參數):

@daily $HOME/bin/cleanup_daily.sh

  那麼 $HOME 會正確地展開。

  不要把計算密集型任務安排在同一時間啓動,比如 @midnight。如果可能的話,在凌晨的幾小時中分散地啓動這些任務,以避免它們爭用資源。

  正如上面提到的,在默認情況下環境變量 SHELL 設置爲 /bin/sh。如果不修改此變量,crontab 中的所有命令都由 /bin/sh 解釋。但是,如果您不熟悉 /bin/sh,更喜歡另一種 shell,那麼可以設置 SHELL 並使用這種 shell 的命令語法。

  例如,如果設置 SHELL=/bin/zsh,那麼所有命令都可以使用 Z shell 的功能,比如它的高級重定向操作符:

SHELL=/bin/zsh
@daily uptime > daily >> weekly

  在這裏,uptime 命令的輸出覆蓋 daily 文件(>daily)並追加到 weekly 文件中(>> weekly)。

  使用訪問控制列表 (ACL) — /etc/cron.allow 和 /etc/cron.deny — 允許或拒絕特定用戶運行 cron 作業。如果希望把對 cron 的訪問權限制在很少幾個用戶,那麼在 /etc/cron.allow 中列出這些用戶的用戶名。未指定的任何用戶都無法使用 crontab 實用程序提交 crontab。但是,如果希望允許大多數人訪問 cron 而拒絕少數用戶,那麼在 /etc/cron.deny 中列出受到限制的用戶。

  例如,如果 /etc/cron.allow 的內容如下:

joe
zelda

  那麼除 Joe 和 Zelda 之外任何用戶都無法訪問 cron:

% whoami
strike
% crontab ~/.crontab
You (strike) are not allowed to use this program (crontab)
See crontab(1) for more information

  要想禁用 cron 發出的電子郵件報告,應該在 crontab 中設置 MAILTO=""。

  再次重申,不要在列表中使用空格。列表值以逗號分隔。在 Vixie cron 中,在範圍中不使用日和月份的名稱。

  要仔細閱讀系統的 cron 文檔。路徑、特性和簡便措施都可能不一樣。在命令行上輸入 man 5 crontab 瞭解 crontab 文件的語法。輸入 man 1 crontab 瞭解 crontab 實用程序。在命令行上輸入 man cron 或 man 8 cron 瞭解 cron 守護進程本身的選項。

  系統管理員最好的朋友

  cron 和與它相似的程序對於系統管理員非常有幫助。如果您需要反覆執行相同任務,就可以考慮用 cron 實現自動化。捕捉具有許多步驟的複雜任務常常需要 shell 腳本,但是許多任務只需要一行命令。

  下面僅僅是一些思路:

  通過組合使用 cron 和數據庫工具,創建每日轉儲。例如,命令:@daily joe mysqldump -pjoespwd accounts > $HOME/backups/accounts.`date +%F`.sql

  每天把數據庫 accounts 轉儲到一個文件。嵌入的日期命令(`date +%F`)確保文件名是惟一的,比如 accounts.2008-08-07.sql。此命令作爲用戶 joe 運行,所以用 -p 指定 Joe 的密碼。此命令還可以放在 Joe 自己的 crontab 中,因爲轉儲需要他的 MySQL 憑證。

  locate 子系統爲系統上的所有文件編制索引,並把每個文件的完整路徑存儲在數據庫中。然後,從命令行查詢此數據庫,就可以立即找到文件。當然,可以根據需要用 find 搜索文件,但是必須等待它搜索文件系統,這可能很慢。

  爲了讓定位子系統發揮作用,必須定期爲文件系統編制索引,因爲隨時可能添加和刪除文件。這種情況就非常適合使用 cron。

0 0,12 * * * root updatedb

  這個 crontab 項每天運行 updatedb(locate 更新實用程序)兩次。

  顯然很適合用 cron 實現自動化的另一個任務是,把文件從主服務器複製到衆多的從服務器。rsync 是一種跨多個系統分佈和同步文件集合的現代實用程序。許多網管都通過組合使用 cron 和 rsync 把網站的主拷貝複製到服務器羣中的每臺服務器。@midnight www rsync -avz /var/www/site slave1:/var/www

  在每天午夜,rsync 都會把 /var/www/site 複製(-avz)到 slave1 上的 /var/www。

  使用命令行實用程序 mail 和 shell 管道操作符(|)把任務的輸出發送給團隊中的一個或多個成員。

@weekly root df --print-type --local -h |& mail -s "Weekly df report" andy bob

  在這裏,每週通過電子郵件把 df 的輸出發送給用戶 Andy 和 Bob,讓他們能夠監視磁盤使用量。

  結束語

  教程結束語

  無論您是單獨使用 UNIX 系統,還是管理有數百位用戶的系統,自動執行維護任務都有助於節省時間、減少錯誤以及保持機器不間斷運行。cron 是在 UNIX 系統上實現自動化的關鍵組件,只需發揮一點兒想像力,就可以讓計算機爲您工作,而不是由您 “伺候” 計算機。
  cron 有助於更輕鬆地完成工作。現在,您可以睡個好覺了。

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