我有一个使用两个单独的grep语句的脚本:
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
脚本首先将目录更改为正确的位置,因此它不是路径问题;除了两个陈述之外,还有相同的文件和可执行文件。
试图解决这个问题真的让我发疯。任何帮助将不胜感激。
感谢。
更新:
我想我已经弄清楚为什么我会得到0.我的表情有一个错误。应该是
grep -E "^[^\"]+\"[^\"]+\" \"[^\"]+\" \"[^\"]+\" \"[^\"-]+\"" tmp.cleaned.log | wc -l
而不是
grep -E "^[^\"]+\"[^\"]+\" \"[^\"]+\" \"[^\"]+\" \"[^\"-\\]+\"" tmp.cleaned.log | wc -l
这就是它返回0(没有匹配)的原因。但是它仍然无法解释为什么我在cron vs shell中看到了不同的结果。我现在意识到10028的值是tmp.cleaned.log的总行数。
所以, 当从shell执行时,grep表达式返回 ALL 行,当它与使用错误正则表达式的任何行匹配时。 当从cron执行相同的错误正则表达式时,grep正确返回 ZERO 行。
我仍然有兴趣了解这种行为差异。
答案 0 :(得分:3)
我认为你会发现差异是由语言环境引起的:
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)中的"
到\
的字符范围包括大写字母和一小组其他字符。正确的区域设置将分别对标点字符和字母进行分组,与其代码点无关。
最有可能的是,您的一个初始文件.bashrc
将LANG
,LC_ALL
或LC_COLLATE
设置为正确的区域设置。这些文件不是由cron
启动的非交互式shell发起的,导致您看到的差异。