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

如何找出脚本文件和二进制文件之间的区别?
$ 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 查看文件获取此信息。但通过命令行,我没有发现任何差异。我无法预测文件是二进制文件还是脚本文件。

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

答案1

只需使用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/*

答案2

事实上,它们之间的差异并没有那么大。

在典型的 Unix 或 Linux 系统上,实际可执行文件少于 5 个。在 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 文件,传递的是打开的文件描述符,而不是文件的名称;这主要是一种优化。解释器是否决定跳转到从文件加载的代码段,还是逐行解释它,仅由解释器决定,并且主要基于惯例。

答案3

文件命令很棒,但对于更专业的分析工具,我希望你尝试一下 TrID 包这是一个文件识别工具。

特尔 ID是 一个 实用 工具 , 旨在 识别 文件 类型 的 二进制 签名 , 并 很 容易 使用 .

欲了解更多信息和套餐,请访问:地点

相关内容