2013-06-06 67 views
2

我有一個使用兩個單獨的grep語句的腳本:grep的crontab中工作不正常

grep -E "GET[^\"]*\.html" tmp.cleaned.log | grep -v "XMLHttpRequest" | wc -l 

,並

grep -E "^[^\"]+\"[^\"]+\" \"[^\"]+\" \"[^\"]+\" \"[^\"-\\]+\"" tmp.cleaned.log | wc -l 

它存儲在輸出日誌文件中所產生的值。當我在shell提示符下手動運行腳本時,我得到了兩個語句的正確結果:680和10028.

但是,當我使用crontab安排腳本時,第一行返回正確的值680,但是第二行結果爲0.

我已將重定向stderr和stdout,並且似乎沒有記錄錯誤。 我還在crontab中添加了SHELL =/bin/bash,另外還在腳本本身中添加了shebang。 在crontab是root用戶,看起來像這樣:

SHELL=/bin/bash 
16  */1  *  *  *  /u02/sites/webstats/rundaily.sh 

腳本通過更改目錄到正確的位置開始,所以它不是路徑問題;除了這兩個語句都指向可執行文件&。

試圖解決這個問題真的讓我發瘋。任何幫助,將不勝感激。

謝謝。

UPDATE

我想我已經想通了,爲什麼我得到0.我的表達,它有一個bug。這本來是

grep -E "^[^\"]+\"[^\"]+\" \"[^\"]+\" \"[^\"]+\" \"[^\"-]+\"" tmp.cleaned.log | wc -l 

,而不是

grep -E "^[^\"]+\"[^\"]+\" \"[^\"]+\" \"[^\"]+\" \"[^\"-\\]+\"" tmp.cleaned.log | wc -l 

這就是爲什麼它返回0(不匹配)的原因。但它仍然不能解釋爲什麼我在cron和shell中看到不同的結果。我現在意識到10028的值是tmp.cleaned.log的總計數。

因此,從shell執行時,grep表達式返回全部行,當它不匹配任何使用錯誤的正則表達式時。 當從cron執行相同的錯誤正則表達式時,grep正確返回了ZERO行。

我仍然對理解這種行爲差異感興趣。

+0

你是直接在你的crontab中執行grep還是在crontab調用的腳本中執行? – Pilou

+0

始終在由crontab調用的腳本中。我嘗試了兩種不同的方法,一種是直接從crontab調用腳本。另一個crontab調用腳本又調用另一個腳本。在這兩種情況下,結果都是一樣的。 – sujitv

回答

2

我想你會發現差異區域設置造成的:

line='A"B" "C" "D" "E"' 
regex="^[^\"]+\"[^\"]+\" \"[^\"]+\" \"[^\"]+\" \"[^\"-\\]+\"" 

LC_COLLATE=en_US.utf8 grep -E "$regex" <<< "$line" # MATCH 
LC_COLLATE=C grep -E "$regex" <<< "$line"   # NO MATCH 

,該字符範圍從"以純ASCII值\(34-92)包括大寫字母和一個小集合其他角色。適當的語言環境將分開標記字符和字母,與代碼點無關。

最有可能的是,您的一個init文件如.bashrcLANG,LC_ALLLC_COLLATE設置爲正確的語言環境。這些文件不是由非交互式shell(如cron開始的)導致的,導致您看到的差異。

+0

你是對的,因爲我的shell中的環境有LANG = en_US.UTF-8 – sujitv

+0

...而從crontab獲得的環境沒有。結果也與您所指出的一致。我用你的代碼測試了我的變化(從最後一個排除類中刪除了\\),結果又與你的建議一致。但我不確定我是否理解推理。爲什麼會試圖排除\結果不匹配 – sujitv

+0

好的。我現在知道了。我試圖排除「, - 和\」,但是,我構造最後一個排除的方式被解釋爲「 - \(即」到\)。這與AZ在該範圍之內或之外的結果是結果在錯誤匹配或匹配。哇,一個糟糕的連字符... – sujitv