スクリプトファイルとバイナリファイルの違いを見つける方法


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を使用してファイルを表示すると、この情報を取得できますが、コマンドラインでは違いは見つかりませんでした。ファイルがバイナリファイルかどうかを予測することはできませんスクリプトファイル。

それでは、コマンドラインを使用してスクリプトファイルとバイナリファイルを区別するにはどうすればよいですか?

回答:


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、ファイルごとに実行して、これがどのタイプのファイルであるかを確認する必要があります。すべてのファイルに簡単な方法はありますか?
アビナッシュラジ

3
特定のディレクトリ内のすべてのファイルの@AvinashRaj?ただやるfile /usr/bin/*。他のコマンドと同じです。
テルドン14

5

実際、それらの違いはそれほど大きくありません。

典型的なUnixまたはLinuxシステムでは、実際の実行可能ファイルは5つ未満です。Ubuntuでは、これらは/lib/ld-linux.so.2/sbin/ldconfigです。

実行可能とマークされている他のすべては、2つの形式がサポートされているインタープリターを介して実行されます。

  1. で始まるファイルに#!は、この文字と最初の改行文字の間にインタープリター名が付けられます(そうです、「スクリプト」がテキストファイルである必要はありません)。
  2. ELFファイルにはPT_INTERP、インタープリター(通常/lib/ld-linux.so.2)へのパスを提供するセグメントがあります。

そのようなファイルが実行されると、カーネルはインタープリターの名前を見つけ、代わりにそれを呼び出します。これは、たとえばシェルスクリプトを実行するときに再帰的に発生する可能性があります。

  1. カーネルはスクリプトを開き#! /bin/sh、最初に見つけます。
  2. カーネルが開き/bin/sh、をPT_INTERP指すセグメントが見つかります/lib/ld-linux.so.2
  3. カーネルが開き/lib/ld-linux.so.2PT_INTERPセグメントがないことがわかり、テキストセグメントを読み込んで起動し、開いているハンドル/bin/shとスクリプト呼び出しのコマンドラインを渡します。
  4. ld-linux.so.2からコードセグメントをロードし、/bin/sh共有ライブラリ参照を解決し、そのメイン機能を開始します
  5. /bin/sh 次に、スクリプトファイルを再度開き、1行ずつ解釈を開始します。

カーネルの観点から見ると、唯一の違いはELFファイルの場合、ファイルの名前ではなく開いているファイル記述子が渡されることです。これは主に最適化です。インタープリターがファイルからロードされたコードセグメントにジャンプするか、行ごとに解釈するかは、インタープリターによってのみ決定され、ほとんどの場合は慣例に基づいています。


良い情報ですが、実際にはこの質問に対する答えではありません。
OrangeDog

答えはMuです。
サイモンリヒター

1

ファイルコマンドは素晴らしいですが、より専門的な分析ツールのために、ファイル識別子ツールであるTrIDパッケージを試してみてください 。

TrIDは、バイナリ署名からファイルタイプを識別するために設計されたユーティリティであり、使いやすいです。

詳細およびパッケージについては、次のWebサイトをご覧ください。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.