我需要在一个目录中找到二进制文件。我希望使用file命令来实现,并且之后将使用grep命令检查结果。但问题是我不知道什么是二进制文件。对于二进制文件,file命令会给出什么信息,或者我应该使用grep检查什么?
这将查找所有非文本、二进制和空文件。
仅使用grep
的解决方案(来自Mehrdad的评论):
最初的回答:
grep -rIL .
这不需要任何其他工具,只需要使用find
和grep
:
find . -type f -exec grep -IL . "{}" \;
-I
参数告诉grep将二进制文件视为不匹配
-L
参数仅打印未匹配的文件
.
匹配任何其他内容
这将查找所有非空二进制文件:
find . -type f ! -size 0 -exec grep -IL . "{}" \;
grep -r -I -L .
? - user541686find
。没有额外的分支,这也会快得多! - t.animal只需要提到Perl的-T
测试文本文件,以及它的相反-B
测试二进制文件。
$ find . -type f | perl -lne 'print if -B'
如果要打印任何二进制文件,请使用-T
进行相反操作:文本文件。
它不是完全可靠的,因为它只查看前1,000个字符左右,但比建议在这里使用的一些临时方法好。详见man perlfunc。以下是摘要:
"-T"和"-B"开关的工作原理如下。首先检查文件的第一个块或其他内容,以查看它是否包含非ASCII字符的有效UTF-8。如果是,则是"-T"文件。否则,该文件的相同部分将被检查是否有奇怪的字符,例如奇怪的控制代码或具有高位设置的字符。如果超过三分之一的字符都很奇怪,则是"-B"文件;否则它是"-T"文件。同时,任何包含在检查部分中的零字节的文件都被认为是二进制文件。
$ 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
⋮
是的,它会读取整个文件,但速度相当快,如果你想要准确性的话...
/bin/tr: line 1, char 41, byte 40: Expecting bytes in the following ranges: 00..7F C2..F4
Fedora, bleeding edge? Nah - undefinedgrep . *
输出:
[...]
Binary file c matches
Binary file e matches
awk
来仅获取文件名,使用 ls
打印权限。请参阅各自的手册页 (man grep
, man awk
, man ls
)。我的第一个回答与这里使用的find
命令基本相同。我认为你的教练想让你了解使用file
命令来理解magic numbers
概念,该命令将其分解为多种类型。
对于我的目的,只需要这么简单:
最初的回答
file * | grep executable
file ./* | grep executable
更安全。 - schmijos使用find
和grep
的答案是可行的,但它非常慢,因为它为每个文件创建一个新进程。以下解决方案更有效:
comm -2 -3 <(find . -type f -not -empty | sort) <(grep -rIl . . | sort)
来自遥远未来的晚回答。这里的首要问题是问题没有明确定义。术语“二进制文件”含糊不清,并且提问者似乎对此感到困惑。
我将同意Wikipedia上的观点:
二进制文件是一种不是文本文件的计算机文件[1]。“二进制文件”通常被用作指代“非文本文件”的术语。
如果不是二进制文件,那么什么是文本文件呢?要识别文本文件,就需要事先知道其编码,否则该文件看起来就像一个未知的二进制文件。
我用来回答“这是什么类型的文件?”问题的工具是file
实用程序。该实用程序足够聪明,可以尝试使用不同的编码读取文件以查看是否有意义:
file
工具可以检测到两种类型的二进制文件::
shopt -s globstar
file -0 **/* | sed -nE 's/\x0:\s*(ELF|data).*//p'
我假设我们主要搜索 ELF 文件作为我们的可执行文件和库格式。还有其他竞争格式,如 COFF 和 PE,所以这些不会被检测到。
我认为确定文件性质的最佳工具是文件实用程序。
在我的一个目录中,唯一被Nautilus文件管理器标识为二进制的文件。
对于这个文件,只有命令ls | xargs file
返回“数据”,没有任何其他信息。
ls
总是一个坏主意。可以用命令 file *
或者递归搜索的方式 shopt -s globstar; file **/*
替代这个命令。 - SenhorLucasLinux中的二进制文件格式为ELF
当您在二进制文件上运行file
命令时,输出包含单词ELF
。您可以使用grep进行搜索。
在命令行上:
file <binary_file_name>
因此,如果您想在目录中查找二进制文件(例如在Linux中),可以执行以下操作:
ls | xargs file | grep ELF
file ./*
。通过 xargs
管道 ls
是不必要的复杂和脆弱的。 - mwfearnley你可以使用find
和参数-executable
,这基本上就是你想要的。
man手册说:
-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
file
命令对它有何描述? - Etan Reisner