首頁 > 軟體

在 Linux 中怎麼使用 cron 計劃任務

2020-06-16 17:01:52

沒有時間執行命令?使用 cron 的計劃任務意味著你不用熬夜程式也可以執行。

系統管理員(在許多好處中)的挑戰之一是在你該睡覺的時候去執行一些任務。例如,一些任務(包括定期迴圈執行的任務)需要在沒有人使用計算機資源的時候去執行,如午夜或週末。在下班後,我沒有時間去執行命令或指令碼。而且,我也不想在晚上去啟動備份或重大更新。

取而代之的是,我使用兩個服務功能在我預定的時間去執行命令、程式和任務。cron 和 at 服務允許系統管理員去安排任務執行在未來的某個特定時間。at 服務指定在某個時間去執行一次任務。cron 服務可以安排任務在一個週期上重複,比如天、周、或月。

在這篇文章中,我將介紹 cron 服務和怎麼去使用它。

常見(和非常見)的 cron 用途

我使用 cron 服務去安排一些常見的事情,比如,每天凌晨 2:00 發生的定期備份,我也使用它去做一些不常見的事情。

  • 許多電腦上的系統時鐘(比如,作業系統時間)都設定為使用網路時間協定(NTP)。 NTP 設定系統時間後,它不會去設定硬體時鐘,它可能會“漂移”。我使用 cron 基於系統時間去設定硬體時鐘。
  • 我還有一個 Bash 程式,我在每天早晨執行它,去在每台電腦上建立一個新的 “每日資訊” (MOTD)。它包含的資訊有當前的磁碟使用情況等有用的資訊。
  • 許多系統進程和服務,像 Logwatchlogrotate、和 Rootkit Hunter,使用 cron 服務去安排任務和每天執行程式。

crond 守護行程是一個完成 cron 功能的後台服務。

cron 服務檢查在 /var/spool/cron 和 /etc/cron.d 目錄中的檔案,以及 /etc/anacrontab 檔案。這些檔案的內容定義了以不同的時間間隔執行的 cron 作業。個體使用者的 cron 檔案是位於 /var/spool/cron,而系統服務和應用生成的 cron 作業檔案放在 /etc/cron.d 目錄中。/etc/anacrontab 是一個特殊的情況,它將在本文中稍後部分介紹。

 

使用 crontab

cron 實用程式執行基於一個 cron 表(crontab)中指定的命令。每個使用者,包括 root,都有一個 cron 檔案。這些檔案預設是不存在的。但可以使用 crontab -e 命令建立在 /var/spool/cron 目錄中,也可以使用該命令去編輯一個 cron 檔案(看下面的指令碼)。我強烈建議你,不要使用標準的編輯器(比如,Vi、Vim、Emacs、Nano、或者任何其它可用的編輯器)。使用 crontab 命令不僅允許你去編輯命令,也可以在你儲存並退出編輯器時,重新啟動動 crond 守護行程。crontab 命令使用 Vi 作為它的底層編輯器,因為 Vi 是預裝的(至少在大多數的基本安裝中是預裝的)。

現在,cron 檔案是空的,所以必須從頭新增命令。 我增加下面範例中定義的作業到我的 cron 檔案中,這是一個快速指南,以便我知道命令中的各個部分的意思是什麼,你可以自由拷貝它,供你自己使用。

  1. # crontab -e
  2. SHELL=/bin/bash
  3. MAILTO=root@example.com
  4. PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin
  5. #For details see man4 crontabs
  6. #Example of job definition:
  7. #.---------------- minute (0-59)
  8. #|  .------------- hour (0-23)
  9. #|  |  .---------- day of month (1-31)
  10. #|  |  |  .------- month (1-12) OR jan,feb,mar,apr ...
  11. #|  |  |  |  .---- day of week (0-6)(Sunday=0or7) OR sun,mon,tue,wed,thu,fri,sat
  12. #|  |  |  |  |
  13. #*  *  *  *  * user-name  command to be executed
  14. # backup using the rsbu program to the internal 4TB HDD andthen4TB external
  15. 0101 * * * /usr/local/bin/rsbu -vbd1 ; /usr/local/bin/rsbu -vbd2
  16. #Set the hardware clock to keep it insyncwith the more accurate system clock
  17. 0305 * * * /sbin/hwclock --systohc
  18. #Perform monthly updates on the first of the month
  19. #25041**/usr/bin/dnf -y update

crontab 命令用於檢視或編?? cron 檔案。

上面程式碼中的前三行設定了一個預設環境。對於給定使用者,環境變數必須是設定的,因為,cron 不提供任何方式的環境。SHELL 變數指定命令執行使用的 shell。這個範例中,指定為 Bash shell。MAILTO 變數設定傳送 cron 作業結果的電子郵件地址。這些電子郵件提供了 cron 作業(備份、更新、等等)的狀態,和你從命令列中手動執行程式時看到的結果是一樣的。第三行為環境設定了 PATH 變數。但即使在這裡設定了路徑,我總是使用每個程式的完全限定路徑。

在上面的範例中有幾個注釋行,它詳細說明了定義一個 cron 作業所要求的語法。我將在下面分別講解這些命令,然後,增加更多的 crontab 檔案的高階特性。

  1. 0101 * * * /usr/local/bin/rsbu -vbd1 ; /usr/local/bin/rsbu -vbd2

在我的 /etc/crontab 中的這一行執行一個指令碼,用於為我的系統執行備份。

這一行執行我自己編寫的 Bash shell 指令碼 rsbu,它對我的系統做完全備份。這個作業每天的凌晨 1:01 (01 01) 執行。在這三、四、五位置上的星號(*),像檔案萬用字元一樣代表一個特定的時間,它們代表 “一個月中的每天”、“每個月” 和 “一周中的每天”,這一行會執行我的備份兩次,一次備份內部專用的硬碟機,另外一次執行是備份外部的 USB 驅動器,使用它這樣我可以很保險。

接下來的行我設定了一個硬體時鐘,它使用當前系統時鐘作為源去設定硬體時鐘。這一行設定為每天凌晨 5:03 分執行。

  1. 0305 * * * /sbin/hwclock --systohc

這一行使用系統時間作為源來設定硬體時鐘。

我使用的第三個也是最後一個的 cron 作業是去執行一個 dnf 或 yum 更新,它在每個月的第一天的凌晨 04:25 執行,但是,我注釋掉了它,以後不再執行。

  1. # 25 04 1 * * /usr/bin/dnf -y update

這一行用於執行一個每月更新,但是,我也把它註釋掉了。

 

其它的定時任務技巧

現在,讓我們去做一些比基本知識更有趣的事情。假設你希望在每週四下午 3:00 去執行一個特別的作業:

  1. 00 15 * * Thu /usr/local/bin/mycronjob.sh

這一行會在每週四下午 3:00 執行 mycronjob.sh 這個指令碼。

或者,或許你需要在每個季度末去執行一個季度報告。cron 服務沒有為 “每個月的最後一天” 設定選項,因此,替代方式是使用下一個月的第一天,像如下所示(這裡假設當作業準備執行時,報告所需要的資料已經準備好了)。

  1. 0203 1 1,4,7,10 * /usr/local/bin/reports.sh

在季度末的下一個月的第一天執行這個 cron 作業。

下面展示的這個作業,在每天的上午 9:01 到下午 5:01 之間,每小時執行一次。

  1. 0109-17 * * * /usr/local/bin/hourlyreminder.sh

有時,你希望作業在業務期間定時執行。

我遇到一個情況,需要作業在每二、三或四小時去執行。它需要用期望的間隔去劃分小時,比如, */3 為每三個小時,或者 6-18/3 為上午 6 點到下午 6 點每三個小時執行一次。其它的時間間隔的劃分也是類似的。例如,在分鐘位置的表示式 */15 意思是 “每 15 分鐘執行一次作業”。

  1. */5 08-18/2 * * * /usr/local/bin/mycronjob.sh

這個 cron 作業在上午 8:00 到下午 18:59 之間,每五分鐘執行一次作業。

需要注意的一件事情是:除法表示式的結果必須是餘數為 0(即整除)。換句話說,在這個例子中,這個作業被設定為在上午 8 點到下午 6 點之間的偶數小時每 5 分鐘執行一次(08:00、08:05、 08:10、 08:15……18:55 等等),而不執行在奇數小時。另外,這個作業不能執行在下午 7:00 到上午 7:59 之間。(LCTT 譯註:此處本文表述有誤,根據正確情況修改)

我相信,你可以根據這些例子想到許多其它的可能性。

 

限制存取 cron

普通使用者使用 cron 存取可能會犯錯誤,例如,可能導致系統資源(比如記憶體和 CPU 時間)被耗盡。為避免這種可能的問題, 系統管理員可以通過建立一個 /etc/cron.allow 檔案去限制使用者存取,它包含了一個允許去建立 cron 作業的使用者列表。(不管是否列在這個列表中,)不能阻止 root 使用者使用 cron。

通過阻止非 root 使用者建立他們自己的 cron 作業,那也許需要將非 root 使用者的 cron 作業新增到 root 的 crontab 中, “但是,等等!” 你說,“不是以 root 去執行這些作業?” 不一定。在這篇文章中的第一個範例中,出現在註釋中的使用者名稱欄位可以用於去指定一個執行作業的使用者 ID。這可以防止特定的非 root 使用者的作業以 root 身份去執行。下面的範例展示了一個作業定義,它以 “student” 使用者去執行這個作業:

  1. 0407 * * * student /usr/local/bin/mycronjob.sh

如果沒有指定使用者,這個作業將以 contab 檔案的所有者使用者去執行,在這個情況中是 root。

 

cron.d

目錄 /etc/cron.d 中是一些應用程式,比如 SpamAssassin 和 sysstat 安裝的 cron 檔案。因為,這裡沒有 spamassassin 或者 sysstat 使用者,這些程式需要一個位置去放置 cron 檔案,因此,它們被放在 /etc/cron.d 中。

下面的 /etc/cron.d/sysstat 檔案包含系統活動報告(SAR)相關的 cron 作業。這些 cron 檔案和使用者 cron 檔案格式相同。

  1. #Run system activity accounting tool every 10 minutes
  2. */10 * * * * root /usr/lib64/sa/sa1 1 1
  3. #Generate a daily summary of process accounting at 23:53
  4. 53 23 * * * root /usr/lib64/sa/sa2 -A

sysstat 包安裝了 /etc/cron.d/sysstat cron 檔案來執行程式生成 SAR。

該 sysstat cron 檔案有兩行執行任務。第一行每十分鐘去執行 sa1 程式去收集資料,儲存在 /var/log/sa 目錄中的一個指定的二進位制檔案中。然後,在每天晚上的 23:53, sa2 程式執行來建立一個每日匯總。

 

計劃小貼士

我在 crontab 檔案中設定的有些時間看上起似乎是隨機的,在某種程度上說,確實是這樣的。嘗試去安排 cron 作業可能是件很具有挑戰性的事, 尤其是作業的數量越來越多時。我通常在我的每個電腦上僅有一些任務,它比起我工作用的那些生產和實驗環境中的電腦簡單多了。

我管理的一個系統有 12 個每天晚上都執行 cron 作業,另外 3、4 個在週末或月初執行。那真是個挑戰,因為,如果有太多作業在同一時間執行,尤其是備份和編譯系統,會耗盡記憶體並且幾乎填滿交換檔案空間,這會導致系統效能下降甚至是超負荷,最終什麼事情都完不成。我增加了一些記憶體並改進了如何計劃任務。我還刪除了一些寫的很糟糕、使用大量記憶體的任務。

crond 服務假設主機計算機 24 小時執行。那意味著如果在一個計劃執行的期間關閉計算機,這些計劃的任務將不再執行,直到它們計劃的下一次執行時間。如果這裡有關鍵的 cron 作業,這可能導致出現問題。 幸運的是,在定期執行的作業上,還有一個其它的選擇: anacron

 

anacron

anacron 程式執行和 cron 一樣的功能,但是它增加了執行被跳過的作業的能力,比如,如果計算機已經關閉或者其它的原因導致無法在一個或多個週期中執行作業。它對筆記型電腦或其它被關閉或進行睡眠模式的電腦來說是非常有用的。

只要電腦一開啟並引導成功,anacron 會檢查過去是否有計劃的作業被錯過。如果有,這些作業將立即執行,但是,僅執行一次(而不管它錯過了多少次回圈執行)。例如,如果一個每週執行的作業在最近三週因為休假而系統關閉都沒有執行,它將在你的電腦一啟動就立即執行,但是,它僅執行一次,而不是三次。

anacron 程式提供了一些對周期性計劃任務很好用的選項。它是安裝在你的 /etc/cron.[hourly|daily|weekly|monthly] 目錄下的指令碼。 根據它們需要的頻率去執行。

它是怎麼工作的呢?接下來的這些要比前面的簡單一些。

1、 crond 服務執行在 /etc/cron.d/0hourly 中指定的 cron 作業。

  1. #Run the hourly jobs
  2. SHELL=/bin/bash
  3. PATH=/sbin:/bin:/usr/sbin:/usr/bin
  4. MAILTO=root
  5. 01 * * * * root run-parts /etc/cron.hourly

/etc/cron.d/0hourly 中的內容使位於 /etc/cron.hourly 中的 shell 指令碼執行。

2、 在 /etc/cron.d/0hourly 中指定的 cron 作業每小時執行一次 run-parts 程式。

3、 run-parts 程式執行所有的在 /etc/cron.hourly 目錄中的指令碼。

4、 /etc/cron.hourly 目錄包含的 0anacron 指令碼,它使用如下的 /etdc/anacrontab 組態檔去執行 anacron 程式。

  1. # /etc/anacrontab: configuration filefor anacron
  2. #See anacron(8)and anacrontab(5)for details.
  3. SHELL=/bin/sh
  4. PATH=/sbin:/bin:/usr/sbin:/usr/bin
  5. MAILTO=root
  6. # the maximal random delay added to the base delay of the jobs
  7. RANDOM_DELAY=45
  8. # the jobs will be started during the following hours only
  9. START_HOURS_RANGE=3-22
  10. #period in days   delay in minutes   job-identifier   command
  11. 1      5      cron.daily              nice run-parts /etc/cron.daily
  12. 7      25     cron.weekly             nice run-parts /etc/cron.weekly
  13. @monthly 45    cron.monthly            nice run-parts /etc/cron.monthly

/etc/anacrontab 檔案中的內容在合適的時間執行在 cron.[daily|weekly|monthly] 目錄中的可執行檔案。

5、 anacron 程式每日執行一次位於 /etc/cron.daily 中的作業。它每週執行一次位於 /etc/cron.weekly 中的作業。以及每月執行一次 cron.monthly 中的作業。注意,在每一行指定的延遲時間,它可以幫助避免這些作業與其它 cron 作業重疊。

我在 /usr/local/bin 目錄中放置它們,而不是在 cron.X 目錄中放置完整的 Bash 程式,這會使我從命令列中執行它們更容易。然後,我在 cron 目錄中增加一個符號連線,比如,/etc/cron.daily

anacron 程式不是設計用於在指定時間執行程式的。而是,用於在一個指定的時間開始,以一定的時間間隔去執行程式,比如,從每天的凌晨 3:00(看上面指令碼中的 START_HOURS_RANGE 行)、從周日(每週第一天)和這個月的第一天。如果任何一個或多個迴圈錯過,anacron 將立即執行這個錯過的作業。

 

更多的關於設定限制

我在我的計算機上使用了很多執行計劃任務的方法。所有的這些任務都需要一個 root 許可權去執行。在我的經驗中,很少有普通使用者去需要執行 cron 任務,一種情況是開發人員需要一個 cron 作業去啟動一個開發實驗室的每日編譯。

限制非 root 使用者去存取 cron 功能是非常重要的。然而,在一些特殊情況下,使用者需要去設定一個任務在預先指定時間執行,而 cron 可以允許他們去那樣做。許多使用者不理解如何正確地設定 cron 去完成任務,並且他們會出錯。這些錯誤可能是無害的,但是,往往不是這樣的,它們可能導致問題。通過設定功能策略,使使用者與管理員互相配合,可以使個別的 cron 作業盡可能地不干擾其它的使用者和系統功能。

可以給為單個使用者或組分配的資源設定限制,但是,這是下一篇文章中的內容。

更多資訊,在 croncrontabanacronanacrontab、和 run-parts 的 man 頁面上,所有的這些資訊都描述了 cron 系統是如何工作的。


作者簡介:

David Both - 是一位 Linux 和開源軟體的倡導者,居住在 Raleigh,North Carolina。他從事 IT 行業超過四十年,並且在 IBM 教授 OS/2 超過 20 年時間,他在 1981 年 IBM 期間,為最初的 IBM PC 寫了第一部培訓教學。他為 Red Hat 教授 RHCE 系列課程,並且他也為 MCI Worldcom、 Cisco、和 North Carolina 州工作。他使用 Linux 和開源軟體工作差不多 20 年了。


via: https://opensource.com/article/17/11/how-use-cron-linux

作者:David Both 譯者:qhwdw 校對:wxy

本文由 LCTT 原創編譯,Linux中國 榮譽推出

本文永久更新連結地址http://www.linuxidc.com/Linux/2017-11/148664.htm


IT145.com E-mail:sddin#qq.com