如何找到脚本文件和二进制文件之间的区别?


11
$ ls -l /usr/bin
total 200732

-rwxr-xr-x 1 root   root     156344 Oct  4  2013 adb
-rwxr-xr-x 1 root   root       6123 Oct  8  2013 add-apt-repository
 list goes long ---------

上面adb是一个二进制文件,add-apt-repository是一个脚本文件。我是通过nautilus查看文件来获得此信息的,但是通过命令行我没有发现任何区别。我无法预测文件是二进制文件还是文件。脚本文件。

那么,如何通过命令行区分脚本文件和二进制文件呢?

Answers:


16

只需使用file

$ file /usr/bin/add-apt-repository
/usr/bin/add-apt-repository: Python script, ASCII text executable
$ file /usr/bin/ab
/usr/bin/ab: ELF 64-bit LSB  shared object, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.32, BuildID[sha1]=569314a9c4458e72e4ac66cb043e9a1fdf0b55b7, stripped

如中所述man file

NAME
   file — determine file type

DESCRIPTION
 This manual page documents version 5.14 of the file command.

 file tests each argument in an attempt to classify it.  There are three
 sets of tests, performed in this order: filesystem tests, magic tests,
 and language tests.  The first test that succeeds causes the file type to
 be printed.

 The type printed will usually contain one of the words text (the file
 contains only printing characters and a few common control characters and
 is probably safe to read on an ASCII terminal), executable (the file con‐
 tains the result of compiling a program in a form understandable to some
 UNIX kernel or another), or data meaning anything else (data is usually
 “binary” or non-printable).  Exceptions are well-known file formats (core
 files, tar archives) that are known to contain binary data.  When adding
 local definitions to /etc/magic, make sure to preserve these keywords.
 Users depend on knowing that all the readable files in a directory have
 the word “text” printed.  Don't do as Berkeley did and change “shell
 commands text” to “shell script”.

您还可以使用技巧来直接在您的可执行文件名上运行此文件$PATH

$ file $(type -p add-apt-repository | awk '{print $NF}')
/usr/local/bin/add-apt-repository: Python script, ASCII text executable
$ file $(type -p ab | awk '{print $NF}')
/usr/bin/ab: ELF 64-bit LSB  shared object, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.32, BuildID[sha1]=569314a9c4458e72e4ac66cb043e9a1fdf0b55b7, stripped

要查找可以在的目录中找到的所有可执行文件的文件类型$PATH,可以执行以下操作:

find $(printf "$PATH" | sed 's/:/ /g') -type f | xargs file

file在特定目录(/usr/bin例如)中的所有文件上运行,只需执行

file /usr/bin/*

但是我们必须file为每个文件运行,以查看这是哪种文件类型。所有文件都有简单的方法吗?
Avinash Raj

3
@AvinashRaj给定目录中的所有文件?做吧file /usr/bin/*。就像其他命令一样。
terdon

5

实际上,两者之间的差异并不是很大。

在典型的Unix或Linux系统上,实际的可执行文件少于五个。在Ubuntu上,这些是/lib/ld-linux.so.2/sbin/ldconfig

标记为可执行的其他所有内容都通过解释器运行,该解释器支持两种格式:

  1. 以文件开头的文件#!的解释器名称将在此字符与第一个换行符之间(没错,没有要求“脚本”为文本文件)。
  2. ELF文件具有一个PT_INTERP段,该段提供了到解释器的路径(通常是/lib/ld-linux.so.2)。

当执行了这样的文件时,内核会找到解释器的名称,然后调用它。这可以递归发生,例如,当您运行shell脚本时:

  1. 内核打开脚本,从头#! /bin/sh开始查找。
  2. 内核打开/bin/sh,找到PT_INTERP指向的段/lib/ld-linux.so.2
  3. 内核将打开/lib/ld-linux.so.2,发现它没有PT_INTERP段,加载其文本段并启动它,将打开的句柄传递到/bin/sh脚本调用的命令行。
  4. ld-linux.so.2从中加载代码段/bin/sh,解析共享库引用并启动其主要功能
  5. /bin/sh 然后重新打开脚本文件,并开始逐行解释它。

从内核的角度来看,唯一的区别是对于ELF文件,传递的是打开文件描述符,而不是文件名。这主要是一种优化。解释器然后决定是跳转到从文件加载的代码段,还是逐行解释它,仅由解释器决定,并且主要基于约定。


很好的信息,但实际上不是这个问题的答案。
OrangeDog 2014年

答案是
Simon Richter

1

File命令很棒,但是对于更专业的分析工具,我希望您尝试使用 TrID软件包,它是一个File Identifier工具。

TrID是一种实用工具,旨在根据其二进制签名识别文件类型,并且易于使用。

有关更多信息和软件包,请访问:网站

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.