linux cron 下的定時(shí)執(zhí)行工具使用技巧

cron是一個(gè)linux下的定時(shí)執(zhí)行工具,可以在無(wú)需人工干預(yù)的情況下運(yùn)行作業(yè)。由于Cron 是Linux的內(nèi)置服務(wù),但它不自動(dòng)起來(lái),可以用以下的方法啟動(dòng)、關(guān)閉這個(gè)服務(wù):
/sbin/service crond start //啟動(dòng)服務(wù)
/sbin/service crond stop //關(guān)閉服務(wù)
/sbin/service crond restart //重啟服務(wù)
/sbin/service crond reload //重新載入配置
你也可以將這個(gè)服務(wù)在系統(tǒng)啟動(dòng)的時(shí)候自動(dòng)啟動(dòng):
在/etc/rc.d/rc.local這個(gè)腳本的末尾加上:
/sbin/service crond start
現(xiàn)在Cron這個(gè)服務(wù)已經(jīng)在進(jìn)程里面了,我們就可以用這個(gè)服務(wù)了,Cron服務(wù)提供以下幾種接口供大家使用:
1.直接用crontab命令編輯
cron服務(wù)提供crontab命令來(lái)設(shè)定cron服務(wù)的,以下是這個(gè)命令的一些參數(shù)與說(shuō)明:
crontab -u //設(shè)定某個(gè)用戶的cron服務(wù),一般root用戶在執(zhí)行這個(gè)命令的時(shí)候需要此參數(shù)
crontab -l //列出某個(gè)用戶cron服務(wù)的詳細(xì)內(nèi)容
crontab -r //刪除沒(méi)個(gè)用戶的cron服務(wù)
crontab -e //編輯某個(gè)用戶的cron服務(wù)
比如說(shuō)root查看自己的cron設(shè)置:crontab -u-root -l
再例如,root想刪除fred的cron設(shè)置:crontab -u fred -r
在編輯cron服務(wù)時(shí),編輯的內(nèi)容有一些格式和約定,輸入:crontab -u-root -e
進(jìn)入vi編輯模式,編輯的內(nèi)容一定要符合下面的格式:*/1 * * * * ls >> /tmp/ls.txt
這個(gè)格式的前一部分是對(duì)時(shí)間的設(shè)定,后面一部分是要執(zhí)行的命令,如果要執(zhí)行的命令太多,可以把這些命令寫到一個(gè)腳本里面,然后在這里直接調(diào)用這個(gè)腳本就可以了,調(diào)用的時(shí)候記得寫出命令的完整路徑。時(shí)間的設(shè)定我們有一定的約定,前面五個(gè)*號(hào)代表五個(gè)數(shù)字,數(shù)字的取值范圍和含義如下:
分鐘 (0-59)
小時(shí)?。?-23)
日期?。?-31)
月份 (1-12)
星期?。?-6)//0代表星期天
除了數(shù)字還有幾個(gè)個(gè)特殊的符號(hào)就是"*"、"/"和"-"、",",*代表所有的取值范圍內(nèi)的數(shù)字,"/"代表每的意思,"*/5"表示每5個(gè)單位,"-"代表從某個(gè)數(shù)字到某個(gè)數(shù)字,","分開幾個(gè)離散的數(shù)字。以下舉幾個(gè)例子說(shuō)明問(wèn)題:
每天早上6點(diǎn)
0 6 * * * echo "Good morning." >> /tmp/test.txt //注意單純echo,從屏幕上看不到任何輸出,因?yàn)閏ron把任何輸出都email到root的信箱了。
每?jī)蓚€(gè)小時(shí)
0 */2 * * * echo "Have a break now." >> /tmp/test.txt
晚上11點(diǎn)到早上8點(diǎn)之間每?jī)蓚€(gè)小時(shí),早上八點(diǎn)
0 23-7/2,8 * * * echo "Have a good dream:)" >> /tmp/test.txt
每個(gè)月的4號(hào)和每個(gè)禮拜的禮拜一到禮拜三的早上11點(diǎn)
0 11 4 * 1-3 command line
1月1日早上4點(diǎn)
0 4 1 1 * command line
每次編輯完某個(gè)用戶的cron設(shè)置后,cron自動(dòng)在/var/cron下生成一個(gè)與此用戶同名的文件,此用戶的cron信息都記錄在這個(gè)文件中,這個(gè)文件是不可以直接編輯的,只可以用crontab -e 來(lái)編輯。cron啟動(dòng)后每過(guò)一份鐘讀一次這個(gè)文件,檢查是否要執(zhí)行里面的命令。因此此文件修改后不需要重新啟動(dòng)cron服務(wù)。
2.編輯/etc/crontab 文件配置cron
cron 服務(wù)每分鐘不僅要讀一次/var/spool/cron內(nèi)的所有文件,還需要讀一次/etc/crontab,因此我們配置這個(gè)文件也能運(yùn)用cron服務(wù)做一些事情。用crontab配置是針對(duì)某個(gè)用戶的,而編輯/etc/crontab是針對(duì)系統(tǒng)的任務(wù)。此文件的文件格式是:
SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root //如果出現(xiàn)錯(cuò)誤,或者有數(shù)據(jù)輸出,數(shù)據(jù)作為郵件發(fā)給這個(gè)帳號(hào)
HOME=/ //使用者運(yùn)行的路徑,這里是根目錄
# run-parts
01 * * * * root run-parts /etc/cron.hourly //每小時(shí)執(zhí)行/etc/cron.hourly內(nèi)的腳本
02 4 * * * root run-parts /etc/cron.daily //每天執(zhí)行/etc/cron.daily內(nèi)的腳本
22 4 * * 0 root run-parts /etc/cron.weekly //每星期執(zhí)行/etc/cron.weekly內(nèi)的腳本
42 4 1 * * root run-parts /etc/cron.monthly //每月去執(zhí)行/etc/cron.monthly內(nèi)的腳本
大家注意"run-parts"這個(gè)參數(shù)了,如果去掉這個(gè)參數(shù)的話,后面就可以寫要運(yùn)行的某個(gè)腳本名,而不是文件夾名了。
了解 cron 概念
cron 守護(hù)進(jìn)程是一個(gè)由實(shí)用程序和配置文件組成的小型子系統(tǒng),在幾乎所有類 UNIX 系統(tǒng)上都可以找到某種風(fēng)格的 cron。cron 的組件包括守護(hù)進(jìn)程本身;一組系統(tǒng)范圍的配置文件;一組針對(duì)特定用戶的配置文件;一個(gè)用來(lái)添加、修改和刪除用戶配置文件的實(shí)用程序;以及一個(gè)簡(jiǎn)單的訪問(wèn)控制設(shè)施。一般來(lái)說(shuō),cron 配置文件或 cron 作業(yè)的列表被稱為 crontab 或 cron 時(shí)間表。
守護(hù)進(jìn)程 cron 連續(xù)運(yùn)行,每分鐘檢查一次配置文件中的修改。cron 讀取系統(tǒng)范圍的和針對(duì)用戶的 crontab(分別在下面兩段中詳細(xì)說(shuō)明)、相應(yīng)地更新事件調(diào)度計(jì)劃并執(zhí)行這一分鐘內(nèi)應(yīng)該執(zhí)行的所有命令。這個(gè)守護(hù)進(jìn)程還捕捉每個(gè)作業(yè)的輸出(如果有輸出的話),并把結(jié)果通過(guò)電子郵件發(fā)送給作業(yè)的所有者。
可以在三個(gè)位置定義與系統(tǒng)相關(guān)的 作業(yè):/etc/crontab、/etc/cron.d 中的任何文件以及特殊目錄 /etc/cron.hourly、/etc/cron.daily、/etc/cron.weekly 和 /etc/cron.monthly:
主要的系統(tǒng) crontab 是/etc/crontab。這個(gè)文件有獨(dú)特的語(yǔ)法(在下一節(jié)中討論),其中定義的每個(gè)作業(yè)根據(jù)它自己的時(shí)間表(比如每小時(shí)兩次或每天一次)作為指定的用戶運(yùn)行。使用 /etc/crontab 調(diào)度各種管理和維護(hù)任務(wù)。
還可以在 /etc/cron.d 目錄中維護(hù)一組 crontab。通過(guò)創(chuàng)建 crontab,按照邏輯對(duì)屬于某一子系統(tǒng)的命令進(jìn)行分組。例如,PHP 5 編程語(yǔ)言的包在 /etc/cron.d 中安裝一個(gè)名為 php5 的 crontab,它會(huì)定期清除不使用的會(huì)話。/etc/cron.d 中的文件采用與 /etc/crontab 相同的語(yǔ)法,每個(gè)作業(yè)按照自己的時(shí)間表并作為特定的用戶運(yùn)行。
還可以把 shell 腳本直接放在 /etc/cron.hourly、/etc/cron.daily、/etc/cron.weekly 或 /etc/cron.monthly 目錄中,這樣就可以每小時(shí)、每天、每周或每月運(yùn)行此腳本一次。放在這里的腳本作為超級(jí)用戶運(yùn)行。
針對(duì)用戶的 crontab 集合通常放在 /var/spool/cron/crontabs 中。(具體位置請(qǐng)參見(jiàn)您的 UNIX 系統(tǒng)文檔。一些系統(tǒng)把用戶 crontab 放在 /usr/lib 中)。但是,不能直接編輯此目錄中的文件,而是使用 crontab 實(shí)用程序創(chuàng)建 crontab 并提交文件。稍后討論如何管理個(gè)人的 crontab。
最后,可以分別使用訪問(wèn)控制文件 /etc/cron.allow 和 /etc/cron.deny 允許或拒絕用戶訪問(wèn) cron。例如,如果某個(gè)用戶的作業(yè)可能會(huì)破壞系統(tǒng)的正常操作,就可以拒絕他訪問(wèn) cron。
如您所見(jiàn),不需要為保持系統(tǒng)不間斷運(yùn)行而犧牲您的休息時(shí)間。只需確定作業(yè)、定義它的調(diào)度計(jì)劃并在適當(dāng)?shù)?crontab 中設(shè)置此作業(yè),然后就可以放心地休息了?,F(xiàn)在就來(lái)看看 cron 文件的特殊語(yǔ)法。
處理 crontab
crontab 僅僅是一個(gè)文本文件,可以用任何 UNIX 編輯器編輯它。它可以包含四種代碼行:空行、注釋、環(huán)境變量設(shè)置和命令。
空行和注釋
文件中的空行和多余的空格被忽略??招泻涂崭裼兄谔岣?crontab 的可讀性,使 crontab 組織有序。
還可以使用注釋對(duì)每個(gè)作業(yè)的時(shí)間表和用途加以說(shuō)明。要想創(chuàng)建注釋,只需在一行的開頭加上一個(gè)井號(hào)(#)。
環(huán)境變量和命令
cron 最終使用一個(gè) shell 執(zhí)行每個(gè)命令??梢酝ㄟ^(guò)環(huán)境變量修改或定制 shell 的行為。
在 crontab 中很容易設(shè)置 shell 環(huán)境變量。只需輸入 VARIABLE=value,把 VARIABLE 替換為變量名,把 value 替換為一個(gè)值。例如,crontab 行:
PATH=/usr/bin:/bin:/usr/local/bin
指定一個(gè)有序的目錄列表作為 shell 搜索路徑。
cron 預(yù)定義了五個(gè)環(huán)境變量:
PATH 的默認(rèn)值是 /usr/bin:/bin。
SHELL 預(yù)設(shè)置為 /bin/sh。
LOGNAME 初始化為 crontab 所有者的用戶名。
HOME 設(shè)置為 crontab 所有者的主目錄,比如 /home/joe。
MAILTO 設(shè)置為 crontab 所有者的名稱。
要想修改這些默認(rèn)值或設(shè)置任何變量,只需在 crontab 中設(shè)置適當(dāng)?shù)沫h(huán)境變量。
當(dāng)然,crontab 可以包含任意數(shù)量的命令行。每個(gè)命令行指定一個(gè)頻率、一個(gè)用戶名(只對(duì)于系統(tǒng) crontab)和一個(gè)要運(yùn)行的任務(wù)。例如,命令:
5 0 * * * root find /tmp -type f -empty -delete
在每天 12:05 a.m(5 0 * * *)刪除 /tmp 中的所有空文件和目錄(find /tmp -type f -empty -delete)。此作業(yè)作為根用戶(root)運(yùn)行。
系統(tǒng) crontab 命令必須指定一個(gè)用戶名,作為運(yùn)行此任務(wù)所用的用戶。(因此,在 /etc/crontab 中可能看到上面的命令)。針對(duì)用戶的 crontab 不能指定用戶名;一個(gè)用戶的 cron 命令總是作為這個(gè)用戶運(yùn)行。是否有用戶名是系統(tǒng) crontab 和用戶 crontab 之間的惟一差異。
下面討論定制時(shí)間表的眾多方式。
定制時(shí)間表
cron 時(shí)間表允許以多種方式運(yùn)行作業(yè),比如每分鐘或在特定日期的特定時(shí)間。調(diào)度的參數(shù)非常靈活。
cron 字段
可以通過(guò)五個(gè)字段調(diào)整頻率:分、小時(shí)、月中日、月份和周中的日期(如周一,周二)。表 1 總結(jié)如何調(diào)整每個(gè)字段。
表 1. cron 作業(yè)的調(diào)度選項(xiàng)
位置 | 字段 | 值 | 說(shuō)明 |
1 | 分 | 0-59 | |
2 | 小時(shí) | 0-23 | |
3 | 月中日 | 1-31 | 與分和小時(shí)不同,月中日不是從零開始的。 |
4 | 月份 | 1-12 | 月份也不是從零開始的。也可以不使用 1-12 的數(shù)字,而是使用月份名的前三個(gè)字母,比如 jan 或 may。 |
5 | 周中日 | 0-7 | 0 和 7 都代表星期日。還可以使用名稱的前三個(gè)字母,比如 mon 或 wed。 |
除了名稱或數(shù)字之外,還可以使用星號(hào)(*)表示 “所有”。例如,在分鐘位置上的星號(hào)表示這一天中的每一分鐘。(在某些情況下確實(shí)需要如此高的頻率,但是一定要小心,以這種頻率執(zhí)行的任務(wù)應(yīng)該非常簡(jiǎn)單,不會(huì)長(zhǎng)時(shí)間運(yùn)行)。
還可以使用值的列表、范圍和步長(zhǎng)(增量)分別指定多個(gè)值、連續(xù)的值范圍和不連續(xù)的值范圍。甚至可以組合使用列表和范圍。列表 是一個(gè)逗號(hào)分隔的值集。范圍 由啟始值和結(jié)束值(含)以及可選的步長(zhǎng)值構(gòu)成。
我們來(lái)看一些示例。表 2 中的每一行包含一個(gè)時(shí)間表及其說(shuō)明。當(dāng)分、小時(shí)和日期字段與當(dāng)前時(shí)間匹配時(shí),cron 會(huì)執(zhí)行命令;如果月中日和周中日受到限制(也就是說(shuō),不是 *),那么當(dāng)這兩個(gè)字段中至少一個(gè) 與當(dāng)前時(shí)間匹配時(shí),cron 也會(huì)執(zhí)行命令。
表 2. cron 作業(yè)的時(shí)間表示例
調(diào)度計(jì)劃 | |||||
分 | 小時(shí) | 月中日 | 月份 | 周中日期 | 說(shuō)明 |
0 | 1 | 15 | 1,3,5,7,9,11 | * | 在 1、3、5、7、9 和 11 月的 15 日的 1 a.m. 運(yùn)行命令。為了更容易理解,也可以把這個(gè)時(shí)間表寫成 0 1 15 jan,mar,may,jul,sep,nov *。在指定列表時(shí),不要在逗號(hào)后面加空格。 |
0-59/15 | * | * | * | * | 這個(gè)調(diào)度計(jì)劃每 15 分鐘運(yùn)行命令一次。 |
30 | * | * | * | wed,fri | 這個(gè)時(shí)間表只在星期三和星期五每小時(shí)的 30 分時(shí)執(zhí)行命令一次。(在列表中可以使用日和月份的名稱,但是在范圍中不可以)。 |
0,30 | 0-5,17-23 | * | * | * | 在午夜到 5 a.m. 以及 7 p.m. 到 11 p.m. 之間整點(diǎn)時(shí)和 30 分時(shí)運(yùn)行命令。 |
0 | 0 | 1 | 1 | * | 在每年 1 月 1 日午夜執(zhí)行命令一次。 |
0 | 0 | * | * | 0 | 在每個(gè)星期日午夜運(yùn)行命令。這相當(dāng)于每周一次。 |
30 | 0 | 10,20,30 | * | 6 | 因?yàn)樵轮腥蘸椭苤腥帐艿较拗?,這個(gè)時(shí)間表在每星期六和每月的 10、20 和 30 日(二月除外)的 12:30 a.m. 運(yùn)行命令。 |
如您所見(jiàn),實(shí)際上可以使用這五個(gè)參數(shù)指定任何調(diào)度計(jì)劃。為了更加簡(jiǎn)便,Vixie cron 還提供了常用調(diào)度計(jì)劃的簡(jiǎn)寫形式。表 3 列出一些簡(jiǎn)寫形式。
表 3. 常用調(diào)度計(jì)劃的簡(jiǎn)寫形式
簡(jiǎn)寫形式 | 說(shuō)明 |
@reboot | 每當(dāng)計(jì)算機(jī)重新引導(dǎo)時(shí)運(yùn)行命令。 |
@daily | 每天一次的簡(jiǎn)寫形式。 |
@weekly | 每周一次的簡(jiǎn)寫形式。 |
@annually | 每年一次的簡(jiǎn)寫形式。也可以寫成 @yearly。 |
@midnight | 在每天午夜運(yùn)行命令。這個(gè)簡(jiǎn)寫形式相當(dāng)于 @daily。 |
如果喜歡使用簡(jiǎn)寫形式,只需用它們替代 cron 命令的前五個(gè)字段。下面這個(gè)命令看起來(lái)簡(jiǎn)單多了。
@daily root /usr/local/scripts/clean_old_files.sh
crontab 命令示例
掌握了基本概念之后,我們來(lái)看一些用戶 crontab 命令示例。同樣的命令也可以應(yīng)用系統(tǒng)范圍:只需在所有系統(tǒng) crontab 項(xiàng)中周中日字段(第五個(gè)字段)后面指定一個(gè)用戶名。
創(chuàng)建個(gè)人 crontab
要想創(chuàng)建個(gè)人 crontab,可以用任何文本編輯器創(chuàng)建一個(gè)文件。按照慣例,個(gè)人 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
通過(guò) crontab 實(shí)用程序提交個(gè)人 crontab
在編輯文件(比如 ~/mycrontab)之后,通過(guò) crontab 實(shí)用程序把它提交給 cron:
% crontab ~/mycrontab
查看 cron 中存儲(chǔ)的信息
要想查看 cron 中存儲(chǔ)的信息,可以輸入 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
在任何時(shí)候,都可以使用 crontab 實(shí)用程序替換您的 crontab。只需提交一個(gè)新文件或同一文件的修訂版。要想刪除 crontab 作業(yè),只需輸入 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 的機(jī)制
盡管 cron 確實(shí)很有用,但是您還應(yīng)該了解可以替代它的兩種機(jī)制。
anacron
如果系統(tǒng)常常關(guān)機(jī)或進(jìn)入休眠狀態(tài)(例如,如果使用 UNIX 筆記本計(jì)算機(jī)的話),那么可以考慮在系統(tǒng)中添加 anacron。anacron 與 cron 的相似之處在于,它也把作業(yè)安排在以后運(yùn)行;但是,與 cron 不同,即使作業(yè)的預(yù)定運(yùn)行時(shí)間已經(jīng)過(guò)了,anacron 也會(huì)運(yùn)行作業(yè)。
例如,如果安排在星期六運(yùn)行文件系統(tǒng)備份,但是系統(tǒng)在星期五到星期一關(guān)機(jī)了,那么當(dāng)系統(tǒng)在星期一重新啟動(dòng)時(shí),anacron 會(huì)立即運(yùn)行星期六的作業(yè)。與之相反,cron 僅僅檢查現(xiàn)在是否應(yīng)該運(yùn)行作業(yè);因此,如果在作業(yè)的預(yù)定運(yùn)行時(shí)間系統(tǒng)是關(guān)閉的,就不運(yùn)行作業(yè)。
anacron 的調(diào)度選項(xiàng)比 cron 少得多。它只能以整天的時(shí)間間隔調(diào)度作業(yè),比如一天、7 天或 30 天;但是對(duì)于那些必須頻繁且可靠地運(yùn)行的作業(yè),它是更好的選擇。
另外,必須從 cron 啟動(dòng) anacron。每當(dāng) anacron 運(yùn)行時(shí),它讀取自己的配置文件。配置文件包含由作業(yè)及其頻率(用天數(shù)表示)組成的配置對(duì)。如果作業(yè)在預(yù)定的時(shí)間沒(méi)有運(yùn)行,anacron 就運(yùn)行此作業(yè)并記錄運(yùn)行作業(yè)的時(shí)間。運(yùn)行完所有作業(yè)之后,anacron 退出。
在大多數(shù) Linux 發(fā)行版上都可以找到 anacron,但是也很容易自己下載并構(gòu)建源代碼。訪問(wèn) anacron 項(xiàng)目頁(yè)面 獲得最新版本。
anacron 的主要配置文件可以在 /etc/anacron 中找到。可以像配置 cron 時(shí)那樣設(shè)置環(huán)境變量,但是更簡(jiǎn)單:
SHELL=/bin/zsh
PATH=/usr/bin:/bin:/usr/local/bin
# format: frequency delay name job
1 10 day-to-day daily.chores.sh
第一個(gè)數(shù)字是周期,所以 1 表示每天運(yùn)行一次,7 表示每 7 天運(yùn)行一次,等等。第二個(gè)數(shù)字是延遲,也就是從 anacron 啟動(dòng)之后到執(zhí)行這個(gè)作業(yè)之間等待的分鐘數(shù)。如果把延遲字段設(shè)置為不同的值,就可以防止所有作業(yè)同時(shí)啟動(dòng)。名稱 day-to-day 只是一個(gè)有幫助的昵稱。配置行的其余部分指定作業(yè);在這里,每天運(yùn)行在指定路徑中找到的 shell 腳本 daily.chores.sh 一次。
anacron 以手冊(cè)頁(yè)形式提供了出色的文檔,還可以在網(wǎng)上找到關(guān)于 anacron 的提示。(請(qǐng)閱讀我在 2007 年 10 月編輯的 Rod Smith 撰寫的 Linux Magazine 文章)。anacron 適合 UNIX 愛(ài)好者和需要額外保障的系統(tǒng)管理員使用。
launchd:cron 的現(xiàn)代替代機(jī)制
cron 確實(shí)是一種功能強(qiáng)大、值得信賴的實(shí)用程序,它的廣泛流行就證明了這一點(diǎn)。Vixie cron 最近又有所改進(jìn),比如增加了簡(jiǎn)寫方式 @reboot,進(jìn)一步簡(jiǎn)化了管理。但是,cron 仍然有一些缺點(diǎn):
盡管可以在 crontab 文件中定義 cron 作業(yè),但是不能從命令行啟動(dòng)和停止 cron 作業(yè)。另外,不能在命令行上創(chuàng)建專用作業(yè)并提交給日歷。
cron 不實(shí)施資源限制。如果作業(yè)作為根用戶運(yùn)行,就能夠消耗無(wú)數(shù)的處理器時(shí)間和內(nèi)存。在實(shí)踐中,可能希望限制一個(gè)作業(yè),以免它影響其他 cron 作業(yè)和系統(tǒng)操作的總體質(zhì)量。
cron 作業(yè)嚴(yán)格地與一個(gè)調(diào)度計(jì)劃相關(guān)聯(lián)。例如,無(wú)法只在發(fā)生某一事件(比如創(chuàng)建一個(gè)文件)時(shí)啟動(dòng)作業(yè)。
從更大的范疇來(lái)看,類 UNIX 系統(tǒng)的許多核心組件都能夠根據(jù)需要啟動(dòng)其他程序,包括 cron、用于網(wǎng)絡(luò)守護(hù)進(jìn)程的 xinetd(或 inetd)和 init(所有系統(tǒng)進(jìn)程的起源)。每個(gè)核心組件都有自己的配置文件,所以很難知道哪個(gè)組件最適合完成某個(gè)修改。
為了克服這些缺點(diǎn),Apple Computer 開發(fā)了一個(gè)統(tǒng)一的啟動(dòng)工具 launchd,它可以在引導(dǎo)時(shí)、根據(jù)需要和按照指定的時(shí)間間隔啟動(dòng)進(jìn)程。實(shí)際上,在 Mac OS 10.4 Tiger 中 launchd 已經(jīng)替代了 cron(和 init 以及用來(lái)引導(dǎo)和初始化系統(tǒng)的其他幾個(gè)系統(tǒng)實(shí)用程序)。(Apple 在系統(tǒng)上保留了 cron,以便為用戶提供方便,而且 Vixie cron 的調(diào)度選項(xiàng)更靈活)。Mac OS X 的引導(dǎo)速度很快確實(shí)可以歸功于 launchd:它會(huì)在引導(dǎo)時(shí)列出要啟動(dòng)的程序,但是只在首次需要時(shí)執(zhí)行程序。
launchd 是開放源碼的,可以從 Mac OS Forge 上它的主頁(yè)獲得源代碼。目前,launchd 已經(jīng)被移植到 FreeBSD 上,但是還沒(méi)有移植到其他 UNIX 或 Linux 系統(tǒng)。但是,許多項(xiàng)目正在積極地實(shí)現(xiàn)與 launchd 等效的程序,所以簡(jiǎn)要地了解它的特性是有必要的:
launchd 并不創(chuàng)建作業(yè)來(lái)檢查目錄中是否有新文件,而是自動(dòng)監(jiān)視目錄中是否有新文件或者監(jiān)視空目錄中是否添加了任何文件,并根據(jù)需要啟動(dòng)作業(yè)。launchd 不執(zhí)行輪詢;而是使用 kqueues 設(shè)施讓內(nèi)核在目錄發(fā)生變化時(shí)通知它。(Linux 具有一種相似的事件設(shè)施 inotify,以后的一篇 developerWorks 文章將討論它) 。
如果指定了,launchd 會(huì)使用 chroot 把您的作業(yè)發(fā)送到一個(gè)新目錄。chroot 讀作 “cha-root”,它是一個(gè)系統(tǒng)調(diào)用,可以改變前向斜杠(/)和根目錄指向的目錄。因此,如果使用 chroot 把文件發(fā)送到 /opt/root,/opt/root 之外的所有文件就是不可訪問(wèn)的(畢竟,/opt/root 現(xiàn)在是 /,也就是文件系統(tǒng)的頂級(jí)目錄),/opt/root 中的所有目錄成為一級(jí)目錄。通常使用 chroot 限制作業(yè),使代碼無(wú)法進(jìn)入更大的文件系統(tǒng),以避免產(chǎn)生損害。
可以為作業(yè)設(shè)置資源限制??梢韵拗频馁Y源包括內(nèi)存、堆棧大小和打開的文件的最大數(shù)量。
當(dāng)定義一個(gè)任務(wù)并把它裝載到 launchd 中之后,可以按照名稱從命令行啟動(dòng)和停止作業(yè)。
launchd 由三個(gè)組件組成:launchd 守護(hù)進(jìn)程本身;用來(lái)添加、修改和刪除作業(yè)以及控制 launchd 的 launchctl 實(shí)用程序;一個(gè)或多個(gè)配置文件,每個(gè)文件定義一個(gè)或多個(gè)作業(yè)。由于它起源于 Mac OS X,launchd 配置文件只是簡(jiǎn)單的屬性文件,可以用 Extensible Markup Language (XML) 表示。
簡(jiǎn)單地說(shuō),在 Mac OS X 上使用 launchd 的步驟如下(要監(jiān)視一個(gè)目錄中添加的文件并根據(jù)需要運(yùn)行作業(yè)):
創(chuàng)建一個(gè)屬性文件來(lái)表達(dá)此作業(yè)及其所有屬性。
可以使用 Mac 的 Property Editor,也可以手工編輯 XML。無(wú)論采用哪種方法,產(chǎn)生的文件都應(yīng)該與 清單 1 相似。
清單 1. 監(jiān)視文件系統(tǒng)目錄變化的 launchd 作業(yè)示例
<?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>
簡(jiǎn)單地說(shuō),當(dāng) /Users/strike/data/incoming 目錄的內(nèi)容發(fā)生變化時(shí),此文件運(yùn)行 /Users/strike/bin/processor 中的實(shí)用程序腳本。把 OnDemand 設(shè)置為 True 讓 launchd 根據(jù)需要啟動(dòng)此作業(yè)。把此文件保存到 ~/Library/LaunchAgents/com.example.processor.plist。
用 launchctl 把此作業(yè)裝載到 launchd 中:% launchctl load ~/Library/LaunchAgents/com.example.processor.plist
如果希望檢查最近的操作或查看保存的作業(yè)的列表,只需輸入 launchctl list。
要想刪除作業(yè),只需帶 unload 選項(xiàng)使用 launchctl:% launchctl unload -w ~/Library/LaunchAgents/com.example.processor.plist
-w 的作用是什么?它完全刪除 launchd 中的作業(yè)。如果沒(méi)有這個(gè)選項(xiàng),作業(yè)會(huì)在登錄時(shí)自動(dòng)地重新裝載(因?yàn)樽鳂I(yè)還在啟動(dòng)代理的用戶集合中)。
launchd 手冊(cè)頁(yè)包含大量信息;如果您是 Mac OS X 用戶,還可以找到大量針對(duì) launchd 的應(yīng)用程序。一些聰明的開發(fā)人員正在把 launchd 遷移到更廣泛的平臺(tái)。
使用 cron 讓工作更輕松
學(xué)習(xí)關(guān)于使用 cron 的一些提示和技巧,了解這個(gè)守護(hù)進(jìn)程和相似的其他程序?yàn)槭裁词悄暮门笥选?/p>
提示和技巧
下面是關(guān)于 cron 的一些提示、技巧和常見(jiàn)的問(wèn)題:
與在終端窗口中使用的 shell 或 shell 腳本不同,cron 并不 在 crontab 文件中就地展開環(huán)境變量。換句話說(shuō),如果在 crontab 中輸入:HOME=/home/joe
PATH=$HOME/bin:/usr/bin:/bin
那么 PATH 并不會(huì)設(shè)置為您期望的路徑。您必須手工展開所有變量,比如:
HOME=/home/joe
PATH=/home/joe/bin:/usr/bin:/bin
但是,因?yàn)槊總€(gè) cron 命令都由 shell 執(zhí)行,所以命令可以 引用變量名。例如,如果在個(gè)人 crontab 中編寫以下命令(注意這一行中省略了用戶名參數(shù)):
@daily $HOME/bin/cleanup_daily.sh
那么 $HOME 會(huì)正確地展開。
不要把計(jì)算密集型任務(wù)安排在同一時(shí)間啟動(dòng),比如 @midnight。如果可能的話,在凌晨的幾小時(shí)中分散地啟動(dòng)這些任務(wù),以避免它們爭(zhēng)用資源。
正如上面提到的,在默認(rèn)情況下環(huán)境變量 SHELL 設(shè)置為 /bin/sh。如果不修改此變量,crontab 中的所有命令都由 /bin/sh 解釋。但是,如果您不熟悉 /bin/sh,更喜歡另一種 shell,那么可以設(shè)置 SHELL 并使用這種 shell 的命令語(yǔ)法。
例如,如果設(shè)置 SHELL=/bin/zsh,那么所有命令都可以使用 Z shell 的功能,比如它的高級(jí)重定向操作符:
SHELL=/bin/zsh
@daily uptime > daily >> weekly
在這里,uptime 命令的輸出覆蓋 daily 文件(>daily)并追加到 weekly 文件中(>> weekly)。
使用訪問(wèn)控制列表 (ACL) — /etc/cron.allow 和 /etc/cron.deny — 允許或拒絕特定用戶運(yùn)行 cron 作業(yè)。如果希望把對(duì) cron 的訪問(wèn)權(quán)限制在很少幾個(gè)用戶,那么在 /etc/cron.allow 中列出這些用戶的用戶名。未指定的任何用戶都無(wú)法使用 crontab 實(shí)用程序提交 crontab。但是,如果希望允許大多數(shù)人訪問(wèn) cron 而拒絕少數(shù)用戶,那么在 /etc/cron.deny 中列出受到限制的用戶。
例如,如果 /etc/cron.allow 的內(nèi)容如下:
joe
zelda
那么除 Joe 和 Zelda 之外任何用戶都無(wú)法訪問(wèn) cron:
% whoami
strike
% crontab ~/.crontab
You (strike) are not allowed to use this program (crontab)
See crontab(1) for more information
要想禁用 cron 發(fā)出的電子郵件報(bào)告,應(yīng)該在 crontab 中設(shè)置 MAILTO=""。
再次重申,不要在列表中使用空格。列表值以逗號(hào)分隔。在 Vixie cron 中,在范圍中不使用日和月份的名稱。
要仔細(xì)閱讀系統(tǒng)的 cron 文檔。路徑、特性和簡(jiǎn)便措施都可能不一樣。在命令行上輸入 man 5 crontab 了解 crontab 文件的語(yǔ)法。輸入 man 1 crontab 了解 crontab 實(shí)用程序。在命令行上輸入 man cron 或 man 8 cron 了解 cron 守護(hù)進(jìn)程本身的選項(xiàng)。
系統(tǒng)管理員最好的朋友
cron 和與它相似的程序?qū)τ谙到y(tǒng)管理員非常有幫助。如果您需要反復(fù)執(zhí)行相同任務(wù),就可以考慮用 cron 實(shí)現(xiàn)自動(dòng)化。捕捉具有許多步驟的復(fù)雜任務(wù)常常需要 shell 腳本,但是許多任務(wù)只需要一行命令。
下面僅僅是一些思路:
通過(guò)組合使用 cron 和數(shù)據(jù)庫(kù)工具,創(chuàng)建每日轉(zhuǎn)儲(chǔ)。例如,命令:@daily joe mysqldump -pjoespwd accounts > $HOME/backups/accounts.`date +%F`.sql
每天把數(shù)據(jù)庫(kù) accounts 轉(zhuǎn)儲(chǔ)到一個(gè)文件。嵌入的日期命令(`date +%F`)確保文件名是惟一的,比如 accounts.2008-08-07.sql。此命令作為用戶 joe 運(yùn)行,所以用 -p 指定 Joe 的密碼。此命令還可以放在 Joe 自己的 crontab 中,因?yàn)檗D(zhuǎn)儲(chǔ)需要他的 MySQL 憑證。
locate 子系統(tǒng)為系統(tǒng)上的所有文件編制索引,并把每個(gè)文件的完整路徑存儲(chǔ)在數(shù)據(jù)庫(kù)中。然后,從命令行查詢此數(shù)據(jù)庫(kù),就可以立即找到文件。當(dāng)然,可以根據(jù)需要用 find 搜索文件,但是必須等待它搜索文件系統(tǒng),這可能很慢。
為了讓定位子系統(tǒng)發(fā)揮作用,必須定期為文件系統(tǒng)編制索引,因?yàn)殡S時(shí)可能添加和刪除文件。這種情況就非常適合使用 cron。
0 0,12 * * * root updatedb
這個(gè) crontab 項(xiàng)每天運(yùn)行 updatedb(locate 更新實(shí)用程序)兩次。
顯然很適合用 cron 實(shí)現(xiàn)自動(dòng)化的另一個(gè)任務(wù)是,把文件從主服務(wù)器復(fù)制到眾多的從服務(wù)器。rsync 是一種跨多個(gè)系統(tǒng)分布和同步文件集合的現(xiàn)代實(shí)用程序。許多網(wǎng)管都通過(guò)組合使用 cron 和 rsync 把網(wǎng)站的主拷貝復(fù)制到服務(wù)器群中的每臺(tái)服務(wù)器。@midnight www rsync -avz /var/www/site slave1:/var/www
在每天午夜,rsync 都會(huì)把 /var/www/site 復(fù)制(-avz)到 slave1 上的 /var/www。
使用命令行實(shí)用程序 mail 和 shell 管道操作符(|)把任務(wù)的輸出發(fā)送給團(tuán)隊(duì)中的一個(gè)或多個(gè)成員。
@weekly root df --print-type --local -h |& mail -s "Weekly df report" andy bob
在這里,每周通過(guò)電子郵件把 df 的輸出發(fā)送給用戶 Andy 和 Bob,讓他們能夠監(jiān)視磁盤使用量。
結(jié)束語(yǔ)
教程結(jié)束語(yǔ)
無(wú)論您是單獨(dú)使用 UNIX 系統(tǒng),還是管理有數(shù)百位用戶的系統(tǒng),自動(dòng)執(zhí)行維護(hù)任務(wù)都有助于節(jié)省時(shí)間、減少錯(cuò)誤以及保持機(jī)器不間斷運(yùn)行。cron 是在 UNIX 系統(tǒng)上實(shí)現(xiàn)自動(dòng)化的關(guān)鍵組件,只需發(fā)揮一點(diǎn)兒想像力,就可以讓計(jì)算機(jī)為您工作,而不是由您 “伺候” 計(jì)算機(jī)。
cron 有助于更輕松地完成工作?,F(xiàn)在,您可以睡個(gè)好覺(jué)了。
相關(guān)文章
Fedora Linux 42 穩(wěn)定版發(fā)布: 帶來(lái)大量新功能和軟件更新
Fedora 42昨日發(fā)布,這是 Red Hat 贊助開發(fā)的杰出前沿 Linux 發(fā)行版的最新版,包含大量新功能和軟件更新,使其成為 2025 年上半年發(fā)布的一款出色的 Linux 操作系統(tǒng)之一,內(nèi)2025-04-16如何在Linux查看硬盤信息? 查看Linux硬盤大小類型和硬件信息的5種方法
使用Linux系統(tǒng)的過(guò)程中,查看和了解硬盤信息是非常重要的工作,尤其是對(duì)于系統(tǒng)管理員而言,那么在Linux系統(tǒng)中如何查看硬盤信息?以下是具體內(nèi)容介紹2025-03-12如何在 Linux 中查看 CPU 詳細(xì)信息? 3招輕松查看CPU型號(hào)、核心數(shù)和溫度
在日常運(yùn)維工作中,獲取 CPU 信息是系統(tǒng)運(yùn)維管理員常見(jiàn)的工作內(nèi)容,無(wú)論是為了性能調(diào)優(yōu)、硬件升級(jí)還是僅僅滿足好奇心2025-03-11什么是 Arch Linux? 獨(dú)樹一幟的Arch Linux發(fā)行版分析
Arch Linux是為簡(jiǎn)化,優(yōu)化,現(xiàn)代化,實(shí)用主義,用戶中心和多功能性而創(chuàng)建Linux發(fā)行版,究竟是什么讓 Arch 與眾不同?下面我們就來(lái)簡(jiǎn)要解讀2025-02-19如何在Linux環(huán)境下制作 Win11裝機(jī)U盤?
一直用的linux辦公,想要將筆記本電腦從 Linux 系統(tǒng)切換回 Windows 11,我們可以制作一個(gè)win11裝機(jī)u盤,詳細(xì)如下2025-02-17Rsnapshot怎么用? 基于Rsync的強(qiáng)大Linux備份工具使用指南
Rsnapshot 不僅可以備份本地文件,還能通過(guò) SSH 備份遠(yuǎn)程文件,接下來(lái)詳細(xì)介紹如何安裝、配置和使用 Rsnapshot,包括創(chuàng)建每小時(shí)、每天、每周和每月的本地備份,以及如何進(jìn)2025-02-06Linux Kernel 6.13發(fā)布:附更新內(nèi)容及新特性解讀
Linux 內(nèi)核 6.13 正式發(fā)布,新版本引入了惰性搶占支持,簡(jiǎn)化內(nèi)核搶占邏輯,通過(guò)減少與調(diào)度器相關(guān)的調(diào)用次數(shù),讓內(nèi)核在運(yùn)行時(shí)表現(xiàn)更優(yōu),從而提高效率2025-01-23五大特性引領(lǐng)創(chuàng)新! 深度操作系統(tǒng) deepin 25 Preview預(yù)覽版發(fā)布
今日,深度操作系統(tǒng)正式推出deepin 25 Preview版本,該版本集成了五大核心特性:磐石系統(tǒng)、全新DDE、Treeland窗口合成器、AI For OS以及Distrobox子系統(tǒng)2025-01-18Linux Mint Xia 22.1重磅發(fā)布: 重要更新一覽
Beta 版 Linux Mint“Xia” 22.1 發(fā)布,新版本基于 Ubuntu 24.04,內(nèi)核版本為 Linux 6.8,這次更新帶來(lái)了諸多優(yōu)化和改進(jìn),進(jìn)一步鞏固了 Mint 在 Linux 桌面操作系統(tǒng)領(lǐng)域的2025-01-16LinuxMint怎么安裝? Linux Mint22下載安裝圖文教程
Linux Mint22發(fā)布以后,有很多新功能,很多朋友想要下載并安裝,該怎么操作呢?下面我們就來(lái)看看詳細(xì)安裝指南2025-01-16