【问题标题】:How to find binary files in a directory?如何在目录中查找二进制文件?
【发布时间】:2015-06-13 13:10:26
【问题描述】:

我需要在一个目录中找到二进制文件。我想用文件来做这个,然后我会用 grep 检查结果。但我的问题是我不知道什么是二进制文件。什么会给二进制文件的文件命令或者我应该用 grep 检查什么?

【问题讨论】:

  • 你在这里说的是什么类型的“二进制”文件?您的系统上是否有适当的“二进制”文件? file 对此有何评论?
  • 我不知道什么样的二进制文件,因为我的作业没有定义它,只有:使用grep命令(和其他)编写一个shell脚本来查找目录中的二进制文件和写下他们的权限。所以我对二进制文件类型一无所知。
  • 这对我来说似乎不够具体。我会要求澄清。虽然给出了使用 grep 的建议,但我猜它的意思是“包含一个 NUL 字节”。
  • 所有文件都是二进制文件。 “二进制”意味着您不知道文件的实际格式,或者它在上下文中并不重要。有些文件是文本文件。文本文件是可以将整个文件解码为具有特定字符编码的文本字符串的文件。所有文件都可以使用几种不同的字符编码进行解码。仅当您知道文件是文本并使用用于编写它的字符编码时,这样做才有效。

标签: linux file grep binary directory


【解决方案1】:

这会查找所有非文本文件、二进制文件和空文件。

编辑

仅使用 grep 的解决方案(来自 Mehrdad 的评论):

grep -rIL .

原答案

这不需要任何其他工具,除了findgrep

find . -type f -exec grep -IL . "{}" \;

-I 告诉 grep 假定二进制文件不匹配

-L 只打印不匹配的文件

. 匹配其他任何东西


编辑 2

这会找到所有非空的二进制文件:

find . -type f ! -size 0 -exec grep -IL . "{}" \;

【讨论】:

  • 这在 OSX 中不起作用,因为它将 html 文件作为二进制文件输出
  • 我认为您可以将其简化为 grep -r -I -L .?
  • 看来你是对的。然而,很久以前我研究过这个,所以我不记得为什么我把find 放在那里。如果没有额外的分叉,它也会更快!
  • 我刚刚运行了这个,它发现了所有“非二进制”文件。
  • 您认为“非二进制”的文件可能是空的?那些也出现了(因为它们不是文本,我猜)
【解决方案2】:

只需要提到 Perl 对文本文件的 -T 测试,以及对二进制文件的相反 -B

$ find . -type f | perl -lne 'print if -B'

将打印出它看到的任何二进制文件。如果您想要相反的内容,请使用 -T:文本文件。

这并不是万无一失的,因为它只查看前 1,000 个字符左右,但它比这里建议的一些临时方法要好。请参阅 man perlfunc 了解整个概要。总结如下:

“-T”和“-B”开关的工作方式如下。第一个块左右 检查文件以查看它是否是有效的 UTF-8,包括 非 ASCII 字符。如果,那么它是一个“-T”文件。否则,同样 检查文件的一部分是否有奇怪的字符,例如奇怪的 设置高位的控制代码或字符。如果超过一个 第三个字符很奇怪,它是一个“-B”文件;否则就是 “-T”文件。此外,检查中包含零字节的任何文件 部分被视为二进制文件。

【讨论】:

    【解决方案3】:

    我对这个问题的第一个答案几乎是使用find 命令在这里嵌入的。我认为您的讲师希望使用file 命令让您了解magic numbers 的概念,该命令将它们分解为多种类型。

    就我的目的而言,它很简单:

    file * | grep executable
    

    但它可以通过多种方式完成。

    【讨论】:

    • 如果您的文件名包含破折号,则使用 file ./* | grep executable 会更安全。
    【解决方案4】:

    由于这是一项任务,如果我给你完整的解决方案,你可能会讨厌我;-) 所以这里有一点提示:

    grep 命令将默认输出二进制文件列表,如果您搜索像 . 这样的正则表达式,它将匹配任何非空文件:

    grep . *
    

    输出:

    [...]
    Binary file c matches
    Binary file e matches
    

    您可以使用awk 仅获取文件名,使用ls 打印权限。请参阅相应的手册页(man grepman awkman ls)。

    【讨论】:

      【解决方案5】:

      在当今时代(2020 毕竟实际上是 21 世纪的第 3 个十年), 我认为正确的问题是如何找到所有非 utf-8 文件? Utf-8 是现代文本文件的等价物。

      具有非 ascii 代码点的文本的 utf-8 编码将引入非 ascii 字节(即设置了最高有效位的字节)。现在,并非所有此类字节的序列都形成有效的 utf-8 序列。

      moreutils 包中的

      isutf8 是您所需要的。

      $ isutf8 -l /bin/*
      /bin/[
      /bin/acyclic
      /bin/addr2line
      /bin/animate
      /bin/applydeltarpm
      /bin/apropos
      ⋮
      

      快速检查:

      $ file $(isutf8 -l /bin/*)
      /bin/[:             ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=4d70c2142fc672d8a69d033ecb6693ec15b1e6fb, for GNU/Linux 3.2.0, stripped
      /bin/acyclic:       ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=d428ea52eb0e8aaf7faf30914710d8fbabe6ca28, for GNU/Linux 3.2.0, stripped
      /bin/addr2line:     ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=797f42bc4f8fb754a49b816b82d6b40804626567, for GNU/Linux 3.2.0, stripped
      /bin/animate:       ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=36ab46e69c1bfea433382ffc9bbd9708365dac2b, for GNU/Linux 3.2.0, stripped
      /bin/applydeltarpm: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=a1fddcbeec9266e698782596f2dfd1b4f3e0b974, for GNU/Linux 3.2.0, stripped
      /bin/apropos:       symbolic link to whatis
      ⋮
      

      您可能希望反转测试并获取所有文本文件。 使用-i

      $ isutf8 -il /bin/*
      /bin/alias
      /bin/bashbug
      /bin/bashbug-64
      /bin/bg
      ⋮
      $ file -L $(isutf8 -il /bin/*)
      /bin/alias:      a /usr/bin/sh script, ASCII text executable
      /bin/bashbug:    a /usr/bin/sh - script, ASCII text executable, with very long lines
      /bin/bashbug-64: a /usr/bin/sh - script, ASCII text executable, with very long lines
      /bin/bg:         a /usr/bin/sh script, ASCII text executable
      ⋮
      

      是的,它会读取整个文件,但速度非常快,而且如果你想要准确的话……

      【讨论】:

        【解决方案6】:

        您可以使用find 和参数-executable,这基本上就是您想要的。

        手册页说:

           -executable
                  Matches files which are executable and directories which are searchable (in a file name resolution sense).  This takes into  account  access control lists and other permissions artefacts which the -perm test ignores.  This test makes use of the access(2) system call, and so can be fooled by NFS servers which do UID mapping (or root-squashing), since many systems implement access(2) in the client's kernel and so  cannot make  use  of  the  UID mapping information held on the server.  Because this test is based only on the result of the access(2) system call, there is no guarantee that a file for which this test succeeds can actually be executed.
        

        这是你想要的结果:

        # find /bin  -executable -type f | grep 'dmesg'
        /bin/dmesg
        

        【讨论】:

        • 但是例如,这会在图片、音乐文件或其他文件上给我一个错误,或者在这种情况下究竟什么是二进制文件?
        • 那么,您想要所有非纯文本文件,对吧?您可以执行以下操作: # for i in * ;做文件 $i | grep -v ASCII | awk -F: '{打印 $1}';完成
        • find-executable 选项是关于权限,而不是文件内容。 OP 明确提到“二进制”,而不是“可执行”文件。
        • 虽然答案不正确,但我仍然觉得它非常有用,因为它可以在包含大量文件的文件夹中查找,给你一个很好的第一次过滤。
        【解决方案7】:

        linux中的二进制文件格式为ELF

        当您在二进制文件上运行file 命令时,输出包含单词ELF。你可以grep这个。

        在命令行上:

        file <binary_file_name>

        所以,如果你想在一个目录中找到二进制文件(例如在 linux 中),你可以这样做:

        ls | xargs file | grep ELF

        【讨论】:

        • 见上面this answer的cmets——并不是所有的二进制文件都是可执行文件;你的答案是错误的。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-08-09
        • 1970-01-01
        • 1970-01-01
        • 2011-09-20
        • 2010-11-04
        • 1970-01-01
        相关资源
        最近更新 更多