web-dev-qa-db-ja.com

ディレクトリ内ですべてのバイナリ実行可能ファイルを再帰的に見つける方法は?

次のようにfindコマンドを使用すると、

find /mydir/mysubdir -executable -type f

すべての実行可能ファイルがリストされ(ディレクトリを除く)、実行可能スクリプトファイル(script.shなど)が含まれます。私がやりたいことは、バイナリ実行可能ファイルのみをリストすることです。

48
uray

fileユーティリティを試してみてください。マンページによると:

マジックテストは、特定の固定フォーマットのデータを含むファイルをチェックするために使用されます。この標準的な例は、バイナリ実行可能ファイル(コンパイル済みプログラム)のa.outファイルで、そのフォーマットはで定義されており、標準のインクルードディレクトリでも定義されています。

正規表現をいじる必要があるかもしれませんが、次のようなものです:

$ find -type f -executable -exec file -i '{}' \; | grep 'x-executable; charset=binary'

fileにはたくさんのオプションがあるので、manページを詳しく見てみるとよいでしょう。私が見つけた最初のオプションは、grepに変換しやすい出力を出力するように見えました。

45
Steven D

スクリプト、つまり最初の2文字が#!であるファイルを除外する方法は次のとおりです。

find -type f -executable -exec sh -c 'test "$(head -c 2 "$1")" != "#!"' sh {} \; -print

一部の種類のファイルについては、それらをバイトコードファイルなどのスクリプトまたはバイナリとして分類するかどうかが明確ではありません。設定方法に応じて、#!で始まる場合と始まらない場合があります。これらが重要な場合は、内部のシェルスクリプトをより複雑にする必要があります。たとえば、ELFバイナリとMono実行可能ファイルとObjective Camlバイトコードプログラムを含め、シェルスクリプトやPerlスクリプトやJVMバイトコードプログラムなどの他の種類の実行可能ファイルは含めない方法を次に示します。

find -type f -executable -exec sh -c '
    case "$(head -n 1 "$1")" in
       ?ELF*) exit 0;;
       MZ*) exit 0;;
       #!*/ocamlrun*) exit 0;;
    esac
    exit 1
' sh {} \; -print

ダウンレベルfindのシステムを見つけた場合に備えて(私が書いているように、RHEL5を実行しているたくさんのサイエンスクラスターがまだあります)、更新する権限がありません。代わりに

find /mypath/ -executable -type f

上記の優れた回答では、たとえば、

find /mypath/h -type f -perm -u+x

許可ビットで検索します。残念ながら、上記はユーザーが実行可能なファイルのみを見つけますが、通常はそれでうまくいきます。

2
TomRoche