2013-06-06 64 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