3

我有一个使用两个单独的 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。

我已经重定向了标准错误和标准输出,并且似乎没有记录错误。我还在 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 和 shell 中看到不同的结果。我现在意识到 10028 的值是 tmp.cleaned.log 的总行数。

因此,当从 shell 执行时,当 grep 表达式使用错误的正则表达式不匹配任何行时,它会返回所有行。从 cron 执行相同的错误正则表达式时,grep 正确返回行。

我仍然有兴趣了解这种行为差异。

4

1 回答 1

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) 中从"到的字符范围包括大写字母和一小组其他字符。\适当的语言环境将分别对标点符号和字母进行分组,与它们的代码点无关。

最有可能的是,您的一个 init 文件(如.bashrcsets LANGLC_ALLLC_COLLATE正确的语言环境。这些文件不是由非交互式外壳(如cron启动外壳)提供的,导致您看到的差异。

于 2013-06-07T23:48:55.897 回答