为什么grep在针对/目录运行时挂起?

jay*_*100 5 unix sockets filesystems crash grep

我的问题分为两部分:

1)当grep"/"下的所有文件时为什么grep会挂起?

例如 :

grep -r 'h' ./
Run Code Online (Sandbox Code Playgroud)

(注意:在挂起/崩溃之前,我注意到我看到一些关于套接字的"没有这样的设备或地址"消息....

当然,我知道grep不应该针对套接字运行,但我认为既然套接字只是Unix中的文件,它应该返回负结果,而不是崩溃.

2)现在,我的后续问题:无论如何 - 我怎么能grep整个文件系统?在执行此操作时是否应该省略某些*NIX目录?特别是,我正在寻找所有最近写的日志文件.

Kei*_*son 16

正如@ninjalj所说,如果你不使用-D skip,grep将尝试读取你所有的设备文件,套接字文件和FIFO文件.特别是在Linux系统(以及许多Unix系统)上,它会尝试读取/dev/zero,这似乎是无限长的.

你会等一会儿.

如果您正在寻找系统日志,从/var/log最开始可能是最好的方法.

如果您正在寻找文件系统中可能存在的任何内容,您可以执行以下操作:

find / -xdev -type f -print0 | xargs -0 grep -H pattern
Run Code Online (Sandbox Code Playgroud)

告诉它保持在单个文件系统中的-xdev论据find; 这将避免/proc/dev(以及任何已安装的文件系统). -type f将搜索限制为普通文件. -print0打印由空字符而不是换行符分隔的文件名; 这可以避免文件中名称中包含空格或其他有趣字符的问题.

xargs读取其标准输入上的文件名(或其他任何内容)列表,并在列表中的所有内容上调用指定的命令.该-0选项适用于find's -print0.

告诉它为每个匹配添加文件名前缀的-H选项grep.默认情况下,grep仅当命令行上有两个或更多文件名时才执行此操作.由于xargs将其参数拆分为批次,因此最后一批可能只有一个文件,这会给您带来不一致的结果.

考虑使用find ... -name '*.log'将搜索限制为名称以.log(假设您的日志文件具有此类名称)和/或使用grep -I ...跳过二进制文件的文件.

请注意,所有这些都取决于GNU特定的功能.其中一些选项可能在MacOS(基于BSD)或其他Unix系统上不可用.请参阅本地文档,并考虑安装GNU findutils(for findxargs)和/或GNU grep.

在尝试任何此操作之前,df请先查看根文件系统的大小.我的目前是268千兆字节; 搜索所有这些可能需要几个小时.花费几分钟(a)限制你搜索的文件和(b)确保命令正确将非常值得你花费的时间.

  • 这比xargs更快:`find/-xdev -type f -exec grep -H {} +`. (2认同)

nin*_*alj 9

默认情况下,grep尝试读取每个文件.使用-D skip跳过设备文件,套接字文件和FIFO文件.


Fre*_*Foo 1

如果您继续看到错误消息,则表示grep没有挂起。在第二个窗口中保持iotop打开状态,以查看系统如何努力将所有内容从存储介质中逐段拉入主内存。这个操作应该很慢,或者你有一个非常准系统的系统。

现在,我的后续问题:无论如何 - 我怎样才能 grep 整个文件系统?执行此操作时是否应该忽略某些 *NIX 目录?特别是,我正在寻找所有最近写入的日志文件。

对整个 FS 进行 Grep 很少是一个好主意。尝试 grep 应该写入日志文件的目录;有可能/var/log。更好的是,如果您知道要查找的文件的名称(例如,它们的扩展名是.log),则可以对这些程序报告的文件执行findlocate操作。grep