第12章 定時任務

来源:http://www.cnblogs.com/f-ck-need-u/archive/2017/06/21/7059418.html
-Advertisement-
Play Games

本文目錄: 12.1 配置定時任務 12.2 crontab file 12.3 crond命令的調試 12.4 精確到秒的任務計劃 12.1 配置定時任務 首先需弄清的概念: (1).crond是一個daemon類程式,路徑為/usr/sbin/crond。預設會以後臺方式啟動,service或s ...



本文目錄:

12.1 配置定時任務

12.2 crontab file

12.3 crond命令的調試

12.4 精確到秒的任務計劃


12.1 配置定時任務

首先需弄清的概念:

(1).crond是一個daemon類程式,路徑為/usr/sbin/crond。預設會以後臺方式啟動,service或systemd方式啟動crond預設也是後臺方式的。

(2).crondtab是管理crontab file的工具,而crontab file是定義定時任務條目的文件。

(3).crontab file存在於多處,包括系統定時任務文件/etc/crontab和/etc/cron.d/*,還有獨屬於各用戶的任務文件/var/spool/cron/USERNAME。

再就是crontab命令:

-l:列出定時任務條目
-r:刪除當前任務列表終端所有任務條目
-i:刪除條目時提示是否真的要刪除
-e:編輯定時任務文件,實際上編輯的是/var/spool/cron/*文件
-u:操作指定用戶的定時任務

執行crontab -e命令編輯當前用戶的crontab file,例如當前為root用戶,則編輯的是/var/spool/cron/root文件。例如寫入下麵這一行。

* * * * * /bin/echo "the first cron entry"  >>/tmp/crond.txt

這將會每分鐘執行一次echo命令,將內容追加到/tmp/crond.txt文件中。

任務計劃中的任務條目如何定義,可以查看/etc/crontab文件。

[root@server2 ~]# cat /etc/crontab
SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root
 
# For details see man 4 crontabs
 
# Example of job definition:
# .---------------- minute (0 - 59)
# |  .------------- hour (0 - 23)
# |  |  .---------- day of month (1 - 31)
# |  |  |  .------- month (1 - 12) OR jan,feb,mar,apr ...
# |  |  |  |  .---- day of week (0 - 6) (Sunday=0 or 7) OR sun,mon,tue,wed,thu,fri,sat
# |  |  |  |  |
# *  *  *  *  * user-name  command to be executed

在此文件中定義了3個變數,其中一個是PATH,該變數極其重要。在最後還給出了任務條目的定義方式:

(1).每個任務條目分為6段,每段以空格分隔,之所以此處多了user-name段是因為/etc/crontab為系統定時任務文件,而一般定時任務是沒有該段的。

(2).前五段為時間的設定段,分別表示"分時日月周",它們的定義不能超出合理值範圍,第六段為所要執行的命令或腳本任務段。

(3).在時間定義段中,使用"*"表示每單位,即每分鐘,每小時,每天,每月,每周幾(仍然是每天)。

(4).每個時間段中,都可以使用逗號","來表示枚舉,例如定義"0,30,50 * * * *"表示每個時辰的整點、第30分鐘和第50分鐘都執行該任務。

(5).每個時間段中,都可以使用"-"定義範圍,可以結合逗號使用。如分鐘段定義了"00,20-30,50"表示每個時辰的整點、第20到30分鐘的每分鐘、第50分鐘都執行該任務。

(6).每個時間段中,使用"/"表示忽略時間,如在小時段定義了"0-13/2"表示在"0/2/4/6/8/10/12"點才滿足時間定義。常使用"*/N"表示每隔多久的意思。例如"00 */2 * * *"表示在每天每隔兩小時的整點執行該任務。

(7).如果定義的日和周衝突了,則會多次執行(不包括因為*號導致的衝突)。例如每月的15號執行該任務,同時又定義了周三執行該任務,正常無衝突情況下,將在周三和每月15號執行,但如果某月的15號同時是周三,則該任務在此日執行兩次。因此,應該儘力避免同時定義周和日的任務。

(8).命令段(即第6段)中,不能隨意出現百分號"%",因為它表示換行的特殊意義,且第一個%後的所有字元串將當作命令的標準輸入。

例如下麵的定義:

* * * * * /bin/cat >>/tmp/crond.txt %"the first %%cron entry%"

該任務輸出的結果將是:

"the first

cron entry
"

所以,在定時任務條目中若以時間定義文件名時,應當將%使用反斜杠轉義。如:

* * * * * cp /etc/fstab /tmp/`date +\%Y-\%m-\%d`.txt

另外一個需要註意的時間段設置是,使用*號導致低級別的時間覆蓋高級別的時間。例如"* */2 * * *",它不表示每兩小時執行一次任務,而是每分鐘執行一次,儘管在小時位上設置了每隔兩小時,但在分鐘位上設置的是每分鐘,所以它仍然表示每分鐘執行一次任務。同理,"*/5 */2 * * *"分鐘位上的設置覆蓋小時位上的設置,表示每5分鐘執行一次而忽略小時位的設置;"00 */2 */5 * *"表示每隔兩小時的整點執行一次任務而忽略天數位的設置。

12.2 crondtab file

crondtab file為任務定義文件。

(1).在此文件中,空行會被忽略,首個非空白字元且以#開頭的行為註釋行,但#不能出現在行中。

(2).可以在crontab file中設置環境變數,方式為"name=value",等號兩邊的空格可隨意,即"name = value"也是允許的。但value中出現的空格必須使用引號包圍。

(3). 預設crond命令啟動的時候會初始化所有變數,除了某幾個變數會被crond daemon自動設置好,其他所有變數都被設置為空值。自動設置的變數包括SHELL=/bin/sh,以及HOME和LOGNAME(在CentOS上則稱為USER),後兩者將被預設設置為/etc/passwd中指定的值。其中SHELL和HOME可以被crontab file中自定義的變數覆蓋,但LOGNAME不允許覆蓋。當然,自行定義的變數也會被載入到記憶體。

(4).除了LOGNAME/HOME/SHELL變數之外,如果設置了發送郵件,則crond還會尋找MAILTO變數。如果設置了MAILTO,則郵件將發送給此變數指定的地址,如果MAILTO定義的值為空(MAILTO=""),將不發送郵件,其他所有情況郵件都會發送給crontab file的所有者。

(5).在系統定時任務文件/etc/crontab中,預設已定義PATH環境變數和SHELL環境變數,其中PATH=/sbin:/bin:/usr/sbin:/usr/bin。

(6).crond daemon每分鐘檢測一次crontab file看是否有任務計劃條目需要執行。

12.3 crond命令的調試

很多時候寫了定時任務卻發現沒有執行,或者執行失敗,但因為crond是後臺運行的,有沒有任何提示,很難進行排錯。但是可以讓crond運行在前端併進行調試的。

先說明下任務計劃程式crond的預設執行方式。

使用下麵三條命令啟動的crond都是在後臺運行的,且都不依賴於終端。

[root@xuexi ~]# systemctl start crond.service
[root@xuexi ~]# service crond start
[root@xuexi ~]# crond

但crond是允許接受選項的。

crond [-n] [-P] [-x flags]
選項說明:
-n:讓crond以前端方式運行,即不依賴於終端。
-P:不重設環境變數PATH,而是從父進程中繼承。
-x:設置調試項,flags是調試方式,比較有用的方式是test和sch,即"-x test""-x sch"。
  :其中test調試將不會真正的執行,sch調試將可以看到等待時間。具體的見下麵的示例。

先看看啟動腳本啟動crond的方式。

[root@server2 ~]# cat /lib/systemd/system/crond.service
[Unit]
Description=Command Scheduler
After=auditd.service systemd-user-sessions.service time-sync.target
 
[Service]
EnvironmentFile=/etc/sysconfig/crond
ExecStart=/usr/sbin/crond -n $CRONDARGS
ExecReload=/bin/kill -HUP $MAINPID
KillMode=process

[Install]
WantedBy=multi-user.target

它的環境配置文件為/etc/sysconfig/crond,該文件中什麼也沒設置。

[root@server2 ~]# cat /etc/sysconfig/crond
# Settings for the CRON daemon.
# CRONDARGS= :  any extra command-line startup arguments for crond
CRONDARGS=

所有它的啟動命令為:/usr/sbin/crond -n。但儘管此處加了"-n"選項,crond也不會前端運行,且不會依賴於終端,這是systemctl決定的。

在解釋下如何進行調試。以下麵的任務條目為例。

[root@server2 ~]# crontab -e
* * * * * echo "hello world" >>/tmp/hello.txt

執行crond並帶上調試選項test。

[root@server2 ~]# crond -x test
debug flags enabled: test
[4903] cron started
log_it: (CRON 4903) INFO (RANDOM_DELAY will be scaled with factor 8% if used.)
log_it: (CRON 4903) INFO (running with inotify support)
log_it: (CRON 4903) INFO (@reboot jobs will be run at computer's startup.)
log_it: (root 4905) CMD (echo "hello world" >>/tmp/hello.txt )

執行crond並帶上調試選項sch。

[root@server2 ~]# crond -x sch
debug flags enabled: sch
[4829] cron started
log_it: (CRON 4829) INFO (RANDOM_DELAY will be scaled with factor 73% if used.)
log_it: (CRON 4829) INFO (running with inotify support)
[4829] GMToff=28800
log_it: (CRON 4829) INFO (@reboot jobs will be run at computer's startup.)
[4829] Target time=1497950880, sec-to-wait=38      # 等待crond daemon下一次的檢測,所以表示38秒後crond將檢測crontab file
user [root:0:0:...] cmd="echo "hello world" >>/tmp/hello.txt "
[4829] Target time=1497950940, sec-to-wait=60
Minute-ly job. Recording time 1497922081
log_it: (root 4831) CMD (echo "hello world" >>/tmp/hello.txt )
user [root:0:0:...] cmd="echo "hello world" >>/tmp/hello.txt "
[4829] Target time=1497951000, sec-to-wait=60
Minute-ly job. Recording time 1497922141
log_it: (root 4833) CMD (echo "hello world" >>/tmp/hello.txt )

但要註意,在sch調試結果中的等待時間是crond這個daemon的檢測時間,所以它表示等待下一次檢測的時間,因此除了第一次,之後每次都是60秒,因為預設crond是每分鐘檢測一次crontab file的。例如,下麵是某次的等待結果,在這幾次等待檢測過程中沒有執行任何任務。

[4937] Target time=1497951720, sec-to-wait=18
[4937] Target time=1497951780, sec-to-wait=60
[4937] Target time=1497951840, sec-to-wait=60

還可以同時帶多個調試方式,如:

[root@server2 ~]# crond -x test,sch
debug flags enabled: sch test
[4914] cron started
log_it: (CRON 4914) INFO (RANDOM_DELAY will be scaled with factor 21% if used.)
log_it: (CRON 4914) INFO (running with inotify support)
[4914] GMToff=28800
log_it: (CRON 4914) INFO (@reboot jobs will be run at computer's startup.)
[4914] Target time=1497951540, sec-to-wait=9
user [root:0:0:...] cmd="echo "hello world" >>/tmp/hello.txt "
[4914] Target time=1497951600, sec-to-wait=60
Minute-ly job. Recording time 1497922741
log_it: (root 4916) CMD (echo "hello world" >>/tmp/hello.txt )

這樣在調試定時任務時間時,也不會真正執行命令。

12.4 精確到秒的任務計劃

預設情況下,crond執行的任務只能精確到分鐘,無法精確到秒。但通過技巧,也是能實現秒級任務的。

(1).方法一:不太精確的方法

寫一個腳本,在腳本中sleep3秒鐘的時間,這樣能實現每3秒執行一次命令。

[root@xuexi ~]# cat /tmp/a.sh
#!/bin/bash
#
PATH="$PATH:/usr/local/bin:/usr/local/sbin"
for ((i=1;i<=20;i++));do
ls /tmp
sleep 3
done
[root@xuexi ~]# cat /var/spool/cron/lisi
* * * * * /bin/bash /tmp/a.sh

但是這樣的方法不是最佳方法,因為執行命令也需要時間,且crond預設會有一個隨機延時,隨機延時由變數RANDOM_DELAY定義。

(2).方法二:在cron配置文件中寫入多條sleep命令和其他命令。

[root@xuexi ~]# cat /var/spool/cron/lisi
* * * * * ls /tmp
* * * * * sleep 3 && ls /tmp
* * * * * sleep 6 && ls /tmp
* * * * * sleep 9 && ls /tmp
* * * * * sleep 12 && ls /tmp
* * * * * sleep 15 && ls /tmp
* * * * * sleep 18 && ls /tmp
* * * * * sleep 21 && ls /tmp
* * * * * sleep 24 && ls /tmp
* * * * * sleep 27 && ls /tmp
* * * * * sleep 30 && ls /tmp
…
* * * * * sleep 57 && ls /tmp

這種方式很繁瑣,但是更精確。如果定義到每秒級別就得寫60行cron記錄。

由此能看出,秒級的任務本就不是crond所擅長的。實際上能用到秒級的任務也比較少。

 

回到系列文章大綱:http://www.cnblogs.com/f-ck-need-u/p/7048359.html

轉載請註明出處:http://www.cnblogs.com/f-ck-need-u/p/7059418.html


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 本例中使用begin tran和with (holdlock)提示來觀察SQL Server在select語句中的鎖。 開啟事務是為了保證時間極短的查詢也能觀察到鎖情況,因為holdlock會在事務結束後釋放鎖。 1. 查詢主鍵索引的select語句 其上鎖情況為: 這裡我選擇了一較為靠前的主鍵值, ...
  • decode()函數是ORACLE PL/SQL是功能強大的函數之一,目前還只有ORACLE公司的SQL提供了此函數,其他資料庫廠商的SQL實現還沒有此功能。 DECODE函數是ORACLE PL/SQL是功能強大的函數之一,目前還只有ORACLE公司的SQL提供了此函數,其他資料庫廠商的SQL實現 ...
  • 1.ctrl+q 打開查詢視窗2.ctrl+/ 註釋sql語句3.ctrl+shift +/ 解除註釋4.ctrl+r 運行查詢視窗的sql語句5.ctrl+shift+r 只運行選中的sql語句6.F6 打開一個MySQL命令行視窗7.ctrl+l 刪除一行8.ctrl+n 打開一個新的查詢視窗9 ...
  • 1.登陸mysql 2.e mysql; 3.比如用戶名密碼為root/root。 你想root使用root從任何主機連接到mysql伺服器的話。 @’ ’後面加ip地址一般般為localhost或者127.0.0.1 * %代表任意ip都可以訪問。 GRANT ALL PRIVILEGES ON ...
  • 本文主要翻譯自 http://hadoop.apache.org/docs/r2.8.0/hadoop-project-dist/hadoop-common/SecureMode.html 譯註:之所以不翻譯為安全模式,是因為namenode啟動的時候有個safemode,如果都翻譯為安全模式,會有 ...
  • 1.檢查當前版本,沒有的話用yum安裝rpm -qa subversion 2.安裝yum install subversion -y2.建庫mkdir -p /home/svn/projectsvnadmin create /home/svn/project3 cd /home/svn/proje ...
  • 去官網找到合適的版本,可以直接下載下來,再用fxp上傳,也可以直接以下麵這種方式下載:$ wget http://download.redis.io/releases/redis-3.2.9.tar.gz $ tar xzf redis-3.2.9.tar.gz $ cd redis-3.2.9 $ ...
  • error: unrecognized command line option ‘-fuse-ld=gold’ linux qt5 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...