2016-01-13 56 views
0

如何設置一個cron執行每10 days16th January開始?這足夠嗎?從1月16日起每10天設置一個cron

30 7 16-15/10 * * command >/dev/null 

7.30 AM16th of every month上面開始和結束上next month 15th並重復每10 days。我不認爲我在上面是正確的。任何人都可以告訴我如何設置cron,以便考慮月末,並且每個10 days命令都從16th January this year 2016開始執行。

+1

cron確實不具備處理該邏輯的能力。你最好每天運行一個包裝腳本來檢查日期並中止或適當地繼續。 –

+0

@WilliamPursell搜索了很多,並意識到它不能。我已經寫了一些東西,可以滿足從2016年1月6日到2016年12月31日的日期範圍。我編寫了7個cron命令。 30 7 6,16,26 1,3 * command>/dev/null 30 7 5,15,25 2,4,5 * command>/dev/null 30 7 4,14,24 6 ,7 *命令>的/ dev/null的 30 7 3,13,23 8 *命令>的/ dev/null的 30 7 2,12,22 9,10 *命令>的/ dev/null的 30 7 1 ,11,21 11,12 *命令>的/ dev/null的 30 7 31 12 *命令>的/ dev/null的 2016是閏年也。我知道這很荒謬,但我是新手,需要編寫腳本的幫助。明年我會改變它。 – jai

+0

您是否希望明年1月16日或每10天無限期運行? –

回答

0

正如William所說,cron本身無法處理這種複雜性。但是,您可以更頻繁地運行cron作業,併爲邏輯使用其他內容。例如;

30 7 16-31 1 * date '+\%j' | grep -q '0$' && yourcommand 
30 7 * 2-12 * date '+\%j' | grep -q '0$' && yourcommand 

此日期格式字符串打印一年中的一天,從001到365的grep -q會做模式匹配,而不是打印結果,但它發現的基礎上,返回一個失敗的成功。每10天,一年中的一天結束於零。那些日子,yourcommand得到運行。

這有一個問題,當年翻車。一個更復雜的選擇可能是在date '+%s'(第二個時代)的產品上做類似的grep,但是你需要做數學運算以將秒轉換爲天,以便通過grep進行分析。這可能會實現(你應該測試):

SHELL=/bin/bash 

30 7 * * * echo $(($(date '+%s')/86400)) | grep '0$' && yourcommand 

(添加您的1月16日的邏輯也是如此,當然)。

這依賴於殼牌算法只能處理整數的事實。殼簡單地截斷而不是四捨五入。


UPDATE

在另一個答案評論,你明確你的要求:

的命令應該開始於1月16日執行,並繼續像1月26日,2月5日,2月15日等 - 佳

爲此,時代的第二種方法是可能是正確的方向。

% date -v1m -v16d -v7H -v30M -v0S '+%s' 
1452947400 

(我在FreeBSD上,因此這些參數爲date。)

SHELL=/bin/bash 

30 7 * * * [[ $((($(date '+\%s') - 1452947400) \% 864000)) == 0 ]] && yourcommand 

此表達式中減去從當前時間7:30 AM年01月16(我的時區)的時代第二,和試驗所得到的差是否是通過10天整除。如果是,則表達式評估爲true並且您的命令運行。請注意,對於$ x的任何值,$((0 % $x))的計算結果均爲0。

如果cron特別忙,並且在計算出數學的一秒鐘內無法完成工作,這可能很容易出錯。

如果你想使這更復雜(也許即使它是複雜),我建議你將邏輯移動到一個單獨的shell腳本來處理日期比較數學。特別是如果你打算添加一個模糊因素,以允許工作失去1秒的窗口..這可能是多行腳本,這是尷尬的維護在一個單一的cronjob條目。

+0

其實我的完整cron可能是這樣的 30 7 * * * php命令emailid $(date「 \%D「) 命令是一個laravel命令,它將日期和電子郵件作爲參數,併爲前10天的事務生成報告。我之前沒有提到過。如果當前日期是2016年1月16日,那麼如果執行了cron,該命令會生成6日和15日之間所有交易的報告。如果我可以每天執行命令並檢查日期參數與2016年1月6日之間的天數差是否爲10的倍數,則生成報告,否則返回。 – jai

0
0 30 7 1/10 * ? * command >/dev/null 

輸出,用於上述表達的是,

Saturday, January 16, 2016 7:30 AM 
    1. Thursday, January 21, 2016 7:30 AM 
    2. Sunday, January 31, 2016 7:30 AM 
    3. Monday, February 1, 2016 7:30 AM 
    4. Thursday, February 11, 2016 7:30 AM 
    5. Sunday, February 21, 2016 7:30 AM 

輸出爲您表達

i.e 30 7 16-15/10 * * command >/dev/null 

    2016-01-15 07:30:00 
    2016-02-15 07:30:00 
    2016-03-15 07:30:00 
    2016-04-15 07:30:00 
    2016-05-15 07:30:00 
    2016-06-15 07:30:00 
    2016-07-15 07:30:00 
    2016-08-15 07:30:00 
    2016-09-15 07:30:00 
    2016-10-15 07:30:00 

最接近的語法將是這樣的:

30 7 1-30/10 * * 
30 7 1-31/10 * * 
30 7 1-28/10 * * 
30 7 1-29/10 * * 

您可以測試cron表達式在這裏http://cron.schlitt.info/

+0

該命令應該從1月16日開始執行,並繼續如1月26日,2月5日,2月15日等 – jai

0

觀察:cron的的數學能力旁邊不存在的。 Unix工具的數學能力是無止境的。

結論:將問題從cron域移到shell域。

解決方案:運行在crontab這每一天30 7 * * * /path/to/script

#!/bin/sh 
PATH=$(/usr/bin/getconf PATH) 
if test $(($(date +%j) % 10)) = 6; then 
    your_command 
fi 

此測試是否天的年中模10 6,喜歡的話是1月16日(與1月6日是已經在過去......)。

在箱子外面思考: 修復您的需求。說服那些有趣的10天週期接受7天週期的人。對於cron來說非常簡單。這是遵循KISS原則。

+0

其實我的全部cron可能是這樣的 30 7 * * * php命令emailid $(date「+ \%D」) 命令是一個laravel命令,它將日期和電子郵件作爲參數並生成報告前10天的交易。我之前沒有提到過。如果當前日期是2016年1月16日,那麼如果執行了cron,該命令會生成6日和15日之間所有交易的報告。如果我可以每天執行命令並檢查日期參數與2016年1月6日之間的天數差是否爲10的倍數,則生成報告,否則返回。 – jai