如果我将数据导入 grep 并传递“-r”标志(递归子目录)并传递“--exclude-dir”标志(例如跳过“.git”目录),则会出现段错误。如果缺少其中任何一项,则没有问题。
$ ls | grep -r --exclude-dir=\.git pattern
Segmentation fault
还有其他人看到这种行为吗?
我在 OSX 上使用 Homebrew 安装的 grep 2.11(最新版本),因为内置的 OSX grep 太旧,不支持我大量使用的功能,例如 '--exclude-dir' 本身。
您可能想知道为什么我要传递这些标志,因为当 grep 过滤 stdin(而不是搜索文件)时它们都没有意义,但原因是我在别名“grp”中指定了这些标志:
alias grp='grep -r --exclude-dir=\.git'
因为我希望每次从命令行手动调用 grp 时它们都默认处于启用状态。我的实际“grp”包含的标志比这多得多,但这些标志今天给我带来了麻烦。
因此,当我去的时候这些标志很有用(并且工作正常):
grp pattern .
我相信它必须扩展到:
grep -r --exclude-dir=\.git pattern .
但是当我在 grep 的“alternate-fire”模式下使用时,这些标志仍然存在,它会过滤 stdin 上的行:
ll | grp pattern
我相信它必须扩展到:
ll | grep -r --exclude-dir=\.git pattern
这就是段错误。删除 '-r' 或 '--exclude-dir',或删除 stdin 上的管道,即可消除段错误。
我查看了生成的核心文件并发现了以下内容:
$ gdb grep /cores/core.31786
GNU gdb 6.3.50-20050815 (Apple version gdb-1515) (Sat Jan 15 08:33:48 UTC 2011)
...
This GDB was configured as "x86_64-apple-darwin"
...
#0 0x00007fff8897ac00 in strlen ()
(gdb) bt
#0 0x00007fff8897ac00 in strlen ()
#1 0x0000000100015576 in excluded_file_name (ex=0x1001005a0, f=0x0) at exclude.c:445
#2 0x0000000100012305 in grepdir (dir=0x0, stats=0x100048620) at main.c:1364
#3 0x0000000100014048 in main (argc=11, argv=0x7fff5fbff0b8) at main.c:2216
因此,这是在从“excluded_file_name”调用的 strlen 中发生段错误。这听起来很相关,但我不知道如何处理这些信息。
这种安排曾经与 MacPorts 的 grep 配合得很好(之前在 Ubuntu 上也如此),所以我猜想我的问题可能是由 Homebrew 引起的。因此,我尝试从 gnu 2.11 源代码编译我自己的 grep,但问题仍然存在。我无法回到 MacPorts - 我不得不出于其他原因切换到 Homebrew,据我所知,它们不能很好地协同工作。
顺便说一句,我不喜欢使用 GREP_OPTIONS 环境变量来设置我的默认值,因为它会破坏我运行的任何内部调用 grep 的工具。
所以,我的问题是:
- 有其他人看到过这种行为吗,还是只有我一个人看到过?
- 我可以阻止 grep 发生分段错误吗?或者只是进一步了解它发生分段错误的原因?
- 我该如何更改别名以便当 stdin 来自管道时从命令中删除 '-r'?
答案1
看起来这可能是与最新发布:
** 新功能
如果没有给出文件操作数,并且给出了命令行 -r 或等效选项,则 grep 现在会搜索工作目录。以前 grep 会忽略 -r 并以非递归方式搜索标准输入。在 GREP_OPTIONS 中找到的 -r 没有这种新效果。
换句话说,行为-r
发生了变化,可能在发布前没有经过详尽的测试。我会向他们发布错误报告 - 这更有可能导致修复。