Chinaunix首页 | 论坛 | 博客
  • 博客访问: 167551
  • 博文数量: 159
  • 博客积分: 7007
  • 博客等级: 准将
  • 技术积分: 1750
  • 用 户 组: 普通用户
  • 注册时间: 2008-06-17 15:05
文章分类

全部博文(159)

文章存档

2010年(39)

2009年(106)

2008年(14)

我的朋友

分类: LINUX

2009-08-04 10:42:05

cron 的問題在於,儘管 crontab 中可用的所有不同選項提供了各種不同的可能性,但仍然有一些惱人的局限。
  每月的最後一天
  例如,要在 cron 中每月最後一天運行命令很困難,因為沒有辦法直接指定此信息。相反,您必須單獨指定月份和其對應的最後一天。例如,在不是閏年的年份,可以結合使用以下三行語句:
  59 23 31 1,3,5,7,8,10,12 * do-something
  59 23 30 4,6,9,11 * do-something
  59 23 28 2 * do-something

  在上面的示例中,通過手動的方式選擇了每個月的最後一天,但管理這三行可能有些麻煩,必須在閏年手動修改 crontab 定義,以確保該信息能計算出正確的日期。


相應的解決辦法是使用 echo 命令(而不是 cron)執行日期檢查。要實現這一點,需要使用 cal(用於輸出當前月份的日曆)和 awk(用於確定該月的最後一天)。如果運行以下命令,應該可獲得月份的最後一天:
  $ echo `cal`|awk '{print $NF}'

  以上命令首先通過 echo 命令(會將通常的多行輸出作為一行輸出)輸出日曆,然後對輸出的數字進行計數;最後的數字就是當前月份的最後一天。
  要在 crontab 中使用此命令,應採用以下方式:
  59 23 * * * [`echo `cal`|awk '{print $NF}'` -eq `date +%d`]
  && do-something

  方括號將在用於運行命令的外殼程序中啟動一個測試。另外要注意,cron 將篩選出 % 符號,因此在 crontab 中使用時必須進行轉義。該測試的第一部分就是前面演示的內容,其第二部分使用 date 命令來輸出當前日期。重複的 && 可確保 && 右側的命令僅在左側的測試結果為真時執行。

  給定周中的特定天

  另一個常見的需求是,僅在每月中的特定星期數運行。例如,可能希望在每個月的第一個星期一或星期五運行一個報告。為了完成此任務,可以使用與上面類似的過程。對於給定周中的任何天,它一定屬於以下日期範圍之一:
  第 1 周:第 1 天到第 7 天
  第 2 周:第 8 天到第 14 天
  第 3 周:第 15 天到第 21 天
  第 4 周:第 22 天到 28 天
  要確定當前日期是否在給定範圍內,例如是否在第四周範圍內,可以使用與以下所示類似的測試:
  [ `date +%e` -gt 21 -a `date +%e` -lt 29 ]
  %e 用於返回當天的號數,如果數字小於 10 則用一個空格(而不是零)作為其前綴,以確保對數字(而非字符串)進行比較。
  現在可以將此與 crontab 定義一起使用,以嘗試每週星期五運行命令:
  59 23 * * 5 [ `date +%e` -gt 21 -a `date +%e` -lt 29 ]
  && do-something

  命令將在每週星期五運行,但由於測試將僅在每個月的第四周返回 True,命令將實際在第三個星期五執行。

  Cron 作業執行環境
  
儘管可以更改執行 cron 作業時使用的環境,但經常最好創建一個包裝腳本,以在運行實際需要的命令前定義任何環境變量(如 PATH)。
  這樣做的部分原因是出於安全考慮;向 cron 作業開放的區域越多,越可能得到包含可疑內容的東西。另一個原因是,這樣可確保即使更改了環境中的一個依賴關係,您的 cron 作業仍然將執行。
  通過使用獨立的包裝腳本,還可以利用不同外殼程序的擴展和功能,而不僅限於通常用於運行大部分 cron 作業的標準 Bourne 外殼程序。
  最後,通過使用獨立的包裝腳本,還允許您為不同命令定義不同的環境。如果您希望在可能使用相同應用程序或工具的不同版本的不同用戶環境中運行命令,這將非常有用。

  記錄輸出的技巧
  
缺省情況下,crontab 運行的生成輸出(到標準輸出和標準錯誤的輸出)的命令都會將輸出以電子郵件的形式發送給該作業的用戶。不過,這並非總是方便的解決方案,對於某些結果,您可能只需要部分輸出,或者可能希望忽略標準輸出,而僅報告錯誤。甚至可能希望將輸出發送到不同的用戶或電子郵件別名。
  可以在 crontab 指定語句中使用重定向來將輸出信息發送到特定文件或忽略來自不同源的輸出。要直接將輸出記錄到文件中,可以使用以下語句:
  1 1 * * * do-something >/var/logs/do-something.log

  上述語句會覆蓋信息,因此,如果希望保持較長時間的記錄,請使用追加:
  1 1 * * * do-something >>/var/logs/do-something.log

  要忽略輸出,請重定向到特殊的 /dev/null 設備。對於標準輸出,請嘗試使用以下語句:
  1 1 * * * do-something >/dev/null

  對於標準輸出和錯誤,請嘗試使用以下語句:
  1 1 * * * do-something >/dev/null 2>&1

  如果希望收集按照日期組織的日誌,則請將 date 命令和指定日誌文件的語句結合使用,例如:
  1 1 * * * do-something >/var/logs/something.`date +%Y%m%d`.log

  要從 cronjob 中的一系列命令拾取和選擇輸出,或創建基於內容的自定義電子郵件,請使用包裝腳本,以將您希望保存的信息寫入到臨時文件中,並同時忽略其他輸出。可以隨後將該文件的內容以電子郵件的方式發送給任何希望的用戶。
  要創建臨時文件,請使用時間和進程 ID 生成唯一的文件名,如下所示:
  LOGFILE=/tmp/`datetime +%Y%m%d`.$$.tempfile
  do-something >$LOGFILE 2>&1
  mailx -s "Results of do-something report" reportees <$LOGFILE
  rm -f $LOGFILE

  將文件發送到相關人員後,請記住刪除該文件。在上面的示例中,使用了 mailx(而不是 mail)來允許設置主題。

阅读(488) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~