findコマンドを使用して実行可能ファイルを検索する


113

find実行可能ファイルを検索するために、Unix コマンドでどのタイプのパラメーター/フラグを使用できますか?


「man find」と入力します。「-executable」はあなたが望むオプションだと思います。
sje397 2010

3
find -executable...しかし、これはリストされたすべてのファイルが実際に実行されることを保証するものではありません
William

1
のすべての実装findが同じであるとは限りません。@ sje397および@Williamが推奨するオプションは使用できない場合があります。以下に示す承認済みのソリューションを使用することをお勧めします。
LS


私は、ファイルのアクセス許可に基づく以下に示すすべての提案を嫌います。引数:私のGNUオペレーティングシステム(Ubuntu)では、たとえばASCIIテキストファイルに "x"(実行可能)フラグを設定できます。この操作の正常な完了を妨げる模倣物はありません。複数の意図しないファイルがxフラグを割り当てられるようにするには、小さな間違い/バグが必要です。したがって、gniourf_gniourfのソリューションは私の個人的なお気に入りです。ただし、クロスコンパイルされた実行可能ファイルにはエミュレータまたはターゲットデバイスが必要であるという欠点があります。
Na13-c 2017

回答:


173

findのGNUバージョンでは、次を使用できます-executable

find . -type f -executable -print

BSDバージョンのfindの場合は、8進数マスク-permと一緒に使用できます+

find . -type f -perm +111 -print

このコンテキストでは、「+」は「これらのビットのいずれかが設定されている」ことを意味し、111は実行ビットです。

これは-executable、GNU findの述語と同じではないことに注意してください。特に、-executable現在のユーザーがファイルを実行できる-perm +111かどうかをテストし、実行権限が設定されているかどうかをテストします。

古いバージョンのGNU findも-perm +111構文をサポートしていますが、4.5.12以降、この構文はサポートされなくなりました。代わりに、を使用-perm /111してこの動作を取得できます。


find: invalid mode ‘+111’findutils 4.5.11 4.fc20でのエラー。
sourcejedi 14

1
@sourcejediありがとう。実際には、GNU以外のバージョンのfind(特にBSD)についてのみ話していましたが、古いバージョンのGNU findは実際にその構文もサポートしていました。新しいバージョンでは、の/代わりに使用する必要があり+ます。詳細については、更新された回答を参照してください。
ローレンスゴンサルベス2014

確かに、私はあなたの答えを誤解しています。より複雑にしてしまい申し訳ありません:)。
sourcejedi 14

場合はシンボリックリンクの実行可能ファイルにも見られなければならない、などが-Lオプションを:find -L ...
mklement0 2015年

「-executable述語と同じではない」と「実行権限が設定されているかどうかをテストするだけ」の影響を理解するのにしばらく時間がかかりました。つまり、現在のユーザーが実際に実行できないファイルである検知が発生する-perm +111可能性があります。エミュレートする方法はありません必要なのだがすることですので、単独の権限をテストすることによっては、関連ファイルのへのユーザーおよびグループIDを現在のユーザーの-executable
mklement0 2015年

35

基本的な誤解を解消するための@ gniourf_gniourfのヒント。

この回答は、既存の回答の概要を提供し、それらの微妙さ相対的なメリットについて説明するとともに、特に移植性に関する背景情報を提供することを目的としています。

実行可能ファイルを見つけると、2つの異なる使用例を参照できます。

  • ユーザー中心現在のユーザー実行可能なファイルを検索します。
  • file-centric:(1つ以上の)実行許可ビットセットが設定されているファイルを検索します。

どちらのシナリオでも実行可能ファイルへのシンボリックリンクを見つけるためだけに使用するのではfind -L ...なく、使用することが理にかなっていることに注意してください。find ...

最も単純なファイル中心のケース-すべての3つのセキュリティプリンシパル(ユーザー、グループ、その他)に対して実行権限ビットが設定されている実行可能ファイルを探すこと通常はですが、必ずしもユーザー中心のシナリオと同じ結果が得られるわけではありません。違いを理解することが重要です。

ユーザー中心(-executable

  • 受け入れ答えは commendably推奨し-executableた場合は、GNUが find利用可能です。

    • GNU findはほとんどのLinuxディストリビューションに付属してます
      • 対照的に、macOSを含むBSDベースのプラットフォームには、それほど強力ではないBSD findが付属しています。
    • シナリオの要求に応じて、現在のユーザーが実行できる-executableファイルのみに一致します(エッジケースがあります。[1])。
  • BSDの find受け入れ答え(が提供する選択肢は-perm +111 回答異なるファイル -centric質問(答え自体が述べたように)。

    • ちょうど使用して-perm答えるようにユーザー -centric質問することであることは不可能必要とされるものがすることですので、関連ファイルのへのユーザーとグループのアイデンティティ現在のユーザのを、一方-permだけをテストすることができ、ファイルのパーミッションを。POSIX 機能
      のみを使用しているため、外部ユーティリティを介さずに質問に答えることはできません。find
    • したがって、(それ自体で)実行できる最善の-perm方法は、の近似です-executableおそらく、近いよりも近似値-perm +111である-perm -111ため、すべてのセキュリティプリンシパル(ユーザー、グループ、その他)のための実行可能なビットがセットされているファイルを検索するよう-これは典型的な現実世界のシナリオとして私を打ちます。おまけとして、POSIXにも準拠しています(find -Lシンボリックリンクを含めるために使用します。説明については、以下を参照してください)。

      find . -type f -perm -111  # or: find . -type f -perm -a=x
  • gniourf_gniourfの答えは、パフォーマンスを犠牲にしても、を使用したの真の移植可能な同等物を-executable提供します-exec test -x {} \;

    • と組み合わせる -exec test -x {} \;-perm +111(つまり、少なくとも1つの実行可能ビットが設定されたファイル)、すべてのファイルexecに対して呼び出す必要がないため、パフォーマンスが向上する可能性があります(以下では、POSIX準拠のBSD find / GNU findを使用しています。詳細については、以下を参照してください)。 :-perm +111-perm /111

      find . -type f \( -perm -u=x -o -perm -g=x -o -perm -o=x \) -exec test -x {} \; -print

ファイル中心(-perm

  • するにはお答えファイル -centric質問にある POSIX準拠の使用するのに十分な-permプライマリー(として知られているテスト GNUの検索用語では)。
    • -perm実行可能性だけでなく、任意のファイル権限をテストできます。
    • アクセス許可は、8進モードまたはシンボリックモードのいずれかとして指定されます。8進モードは8進数(例:)ですが111、シンボリックモードは文字列(例:)a=xです。
    • シンボリックモードは、セキュリティプリンシパルをu(ユーザー)、g(グループ)およびo(その他)として識別するかa、3つすべてを参照します。xたとえば、アクセス許可は実行可能ファイルの場合と同様に表現され、演算子=+およびを使用してプリンシパルに割り当てられ-ます。以下のために進モードでを含む完全な議論、参照のためのPOSIX仕様chmodユーティリティを
    • の文脈ではfind
      • モードの接頭辞-(たとえば-ug=x)は、指定されたすべての権限を持つファイルに一致することを意味します(ただし、一致するファイルには追加の権限がある場合があります)。
      • 持つNO接頭辞(例えば755、この持って試合ファイル:)手段フル、正確な一連の権限を。
      • 警告GNU findとBSD findはどちらも、are-Any-of-the-specified-permission-bits-set logicを使用し追加の非標準プレフィックスを実装しますが、互換性のない構文を使用して実装します
        • BSD find: +
        • GNU find:/ [2]
      • したがって、コードを移植可能にする必要がある場合は、これらの拡張機能を使用しないでください
  • 以下の例は、ファイル中心のさまざまな質問に対する移植可能な回答を示しています。

ファイル中心のコマンドの例

注意:

  • 次の例はPOSIX準拠です。つまり、GNU検索やBSD検索を含む、POSIX互換の実装で機能するはずです。具体的には、以下が必要です。
    • 非標準モードの接頭辞+またはを使用しない/
    • 論理演算子プライマリのPOSIX形式を使用します。
      • !NOT(GNU findとBSD findも許可します-not); シェルの履歴の拡張から\!保護するために例で使用されていることに注意してください!
      • -aANDの場合(GNU検索とBSD検索も許可します-and
      • -oORの場合(GNU検索とBSD検索も許可します-or
  • これらの例では、読みやすく、覚えやすいため、シンボリックモードを使用しています。
    • モードプレフィックス-を使用する=と、and +演算子は互換的に使用できます(たとえば、後で適用しない限り- -u=xと同等-u+xですが-x、それを行う意味がありません)。
    • ,部分モードを結合するために使用します。ANDロジックが暗示されます。たとえば、-u=x,g=xユーザーグループの両方の実行可能ビットを設定する必要があることを意味します。
    • モード自体は、「このビットが設定されていない場合にのみ一致する」という意味で否定的な一致を表すことはできません。-permNOTプライマリを含む別の式を使用する必要があります!
  • 検索のことを注意予備選挙(のような-print、または-perm;としても知られているアクションテスト GNUの検索では)されている暗黙的に参加しました-a(論理AND)、およびその-o可能性と括弧(のようにエスケープ\(して\)シェルのため)が実装したり、ロジックために必要とされています。
  • find -L ...シンボリックリンクを実行可能ファイル find ...にも一致させるために、単に使用されるのではなく
    • -Lシンボリックリンク自体ではなく、シンボリックリンクのターゲットを評価するようにfindに指示します。したがって、がなければ-L-type fシンボリックリンクを完全に無視します。
# Match files that have ALL executable bits set - for ALL 3 security
# principals (u (user), g (group), o (others)) and are therefore executable
# by *anyone*.
# This is the typical case, and applies to executables in _system_ locations
# (e.g., /bin) and user-installed executables in _shared_ locations
# (e.g., /usr/local/bin), for instance. 
find -L . -type f -perm -a=x  # -a=x is the same as -ugo=x

# The POSIX-compliant equivalent of `-perm +111` from the accepted answer:
# Match files that have ANY executable bit set.
# Note the need to group the permission tests using parentheses.
find -L . -type f \( -perm -u=x -o -perm -g=x -o -perm -o=x \)

# A somewhat contrived example to demonstrate the use of a multi-principial
# mode (comma-separated clauses) and negation:
# Match files that have _both_ the user and group executable bit set, while
# also _not_ having the other executable bit set.
find -L . -type f -perm -u=x,g=x  \! -perm -o=x

[1] GNU find 4.4.2 -executable以降の記述man find

実行可能なファイルと検索可能なディレクトリに一致します(ファイル名解決の意味で)。これは、アクセス制御リストと、-permテストが無視するその他の権限アーティファクトを考慮に入れています。このテストはaccess(2)システムコールを利用するため、多くのシステムがクライアントのカーネルにaccess(2)を実装しているため、UIDマッピング(またはルートスカッシング)を実行するNFSサーバーに騙される可能性があります。サーバーに保持されているUIDマッピング情報。このテストはaccess(2)システムコールの結果のみに基づいているため、このテストが成功したファイルが実際に実行できるという保証はありません。

[2] 4.5.12より前の GNU findバージョンでもprefixを使用できました+が、これは最初に非推奨になり、最終的には削除されました。これは+シンボリックモードと組み合わせると、正確な権限マスクとして解釈されるため、予期しない結果が生じる可能性があるためです。場合は、あなた()バージョンの実行前に 4.5.12 および(b)はに自分自身を制限モードのみ、あなたは可能性が使用して逃げる+両方 GNU見つけて、BSDは見つけるが、それは良い考えではありません。


2
これまでで最も包括的なSOの答えは?;)
andynormancx 2018

@andynormancx :)まあ、箇条書きの数に関しては、この候補を提供できます。
mklement0 2018

11

現在のユーザーが実行可能なファイルを見つける別の可能性1があるように:

find . -type f -exec test -x {} \; -print

(ここでのテストコマンドはPATHにあるもの/usr/bin/testで、組み込みではありません)。


1-executableフラグがfind利用できない場合にのみこれを使用してください!これは-perm +111ソリューションとは微妙に異なります。


2
これは機能しますが、かなり低速です。また、シェルに応じて、あなたは次のように、ラップやファイル名のプレースホルダをエスケープする必要がある場合があります'{}'\{\}
イオノクラストブリガム

1
@ mklement0これは、doの-executableように、または私のコマンドのように、実行可能なコマンドを見つけられません。
gniourf_gniourf 2015年

1
ありがとう、@ gniourf_gniourf-本当にいくつか誤解がありました。私は少なくとも今のところ私の答えを削除しているので、他のコメントをここに転載します(おそらく復元可能なものがある場合、復活する可能性があります): " find . -type f -perm -u=xは次と同等ではありません-executable-executableユーザーが実行できるすべてのファイルに一致します。g+x適切なグループまたはにいる場合o+x。実際に-perm -u=xは、ユーザーが実行できない多くのファイルが見つかり、そのユーザーが実行できるいくつかのファイルを見逃してしまいます。」
mklement0 2015年

1
@IonoclastBrigham:引用{}する必要があるのは仮想的な必要性です(そして引用することで害はありません)が、実際にはPOSIXのようなシェルやでは必要ありませんcsh。シェル必要な場所を知っていますか?
mklement0 2015年

4
@IonoclastBrigham:興味深い、ありがとう。したがって、ではfish{}実際に'{}'またはとしてエスケープする必要があります\{\}。、、およびは同じ種類のブレース展開を提供することbashに注意してください。しかし、彼らは引用符で囲まれていないトークンを印刷しないでと(したがって:エスケープは不要)を、彼らはそれを検討していないため、有効なブレース式(彼らは少なくとも必要と2つのトークン、または有効な数値連続式)を、一方 と見なし有効ブレースその結果表現は空の文字列。kshzsh{} fish{}
mklement0 2015年

9

-executableテストフラグを使用できます。

-executable
              Matches files which are executable  and  directories  which  are
              searchable  (in  a file name resolution sense).

4
-executableはおそらく未知のオプションです。
実は

4
それはGNU Find拡張機能でしょうか?タグはLinuxではなくUnixであるため、少なくともGNU拡張機能はそのように文書化する必要があります。
ジョナサンレフラー、

3
このオプションは、少なくともOS XにあるBSD findコマンドではサポートされていません。これはGNU拡張機能ですが、他の種類のfindでもサポートされている可能性があります。
Ionoclast Brigham、2012

FWIW、私はこれがsles 10ではなく、sles> = 11にあることを発見しました(それによって少し燃やされました)
Peter Turner

これは実際にはすべての例を取得するわけではないことに注意してください。私の場合、所有し-rw-r-xr-x-executableいないファイルが検出されませんでした
Dezza

2

これは私にとってうまくいき、共有することを考えました...

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

13
ほんの数千のケースだけ、そしてあなたは再発明しましたfile
tripleee 2013年

@tripleee +1。クールなのはこの拡張です:find ./ -mime application/x-sharedlib -o -mime application/x-dosexec
ダニエル・アルダー

@Daniel Alder、どのバージョンのfindを使用しますか?検索でオプション-mimeが見つかりませんでした(GNU findutils)4.4.2
AjayKumarBasuthkar

@tripleee +1。'file'&/ 'mimetype'を利用するのは良い考えです。または、-mimeをサポートするfindバージョンを見つけてください。
AjayKumarBasuthkar 2014

2
find . -executable -type f

ファイルが実行可能であることを実際に保証するものではなく、実行ビットが設定されたファイルを検索します。もし、するなら

chmod a+x image.jpg

上記の検索では、実際に実行ビットが設定されたjpegイメージであっても、image.jpgは実行可能ファイルであると見なされます。

私は通常これで問題を回避します:

find . -type f -executable -exec file {} \; | grep -wE "executable|shared object|ELF|script|a\.out|ASCII text"

検索で実行可能ファイルに関するドーム情報を実際に出力したい場合は、次のようにします。

find . -type f -executable -printf "%i.%D %s %m %U %G %C@ %p" 2>/dev/null |while read LINE
do
  NAME=$(awk '{print $NF}' <<< $LINE)
  file -b $NAME |grep -qEw "executable|shared object|ELF|script|a\.out|ASCII text" && echo $LINE
done

上記の例では、ファイルの完全パス名が最後のフィールドにあり、ファイル名が他の場所にある場合は、awk "NAME = $(awk '{print $ NF}' <<< $ LINE)"で検索する場所を反映する必要があります「NF」を正しい数値位置に置き換えるために必要な検索出力文字列。セパレータがスペースでない場合は、セパレータをawkに通知する必要もあります。


1

SOでばかげこれは超簡単ではないことを...おろか隣不可能に。手を挙げて、私はApple / Spotlightに頼る...

mdfind 'kMDItemContentType=public.unix-executable'

少なくともそれはうまくいきます!


mdfindOSX について知っておくと便利です。uourコマンドは、システム全体の Unix実行可能ファイルを報告することに注意してください。mdfind -onlyin . 'kMDItemContentType=public.unix-executable'結果を現在のディレクトリのサブツリーに制限します。細かい点:検索を特定のディレクトリのみ(サブフォルダーなし)に制限することは明らかにサポートされていません。実行可能ファイルへのシンボリックリンクは明らかに含まれていません。不思議なことに、いったんmdfind実行可能ファイルが見つかると、その後、実行可能ビットを削除することできません
mklement0 2015年

Spotlightが実行可能なUnixファイルを検出/非検出する方法にバグを見つけたと思います。私はAppleにバグを報告しopenradar.me/20162683に報告しました。また、でバグにバグを報告するために-私はあなたを奨励-そして誰がこの機能に興味を持っbugreport.apple.com
mklement0

(コメントが急いで申し訳ありませんが、うまくいけば、それらは今は正しいです)のmdfind -onlyin . 'kMDItemContentType=public.unix-executable'ように動作find . -type f -perm +111 -printします。それはそれはしてファイルを見つけ、ある任意の生じることが実行可能なビットセット、偽陽性を(つまり、実際には問題ではないかもしれないけれども) -真にだけで実行可能ファイルを見つけるために、現在のユーザー BSDの検索を使用して、@ gniourf_gniourfの回答を参照してください。findベースのソリューションを使用すると、実行可能ファイルへのシンボリックリンクを見つけることができるという利点があります(オプション-Lmdfind
mklement0 2015年

1
@ mklement0私の答えは装飾を避けました -ポイントホームを釘付けにしようとしていますが-はい、このフォームを「非警告」とすることはほとんどありません。別のオプション-それが現れるかどうかわからない- ls /Applications/**/*(*)あなたの(私の?)zshシェル
Alex Grey

便利なzshヒントをありがとう-それを知りませんでした。(実行可能ファイル()またはシンボリックリンク()のいずれかを一致させることができるようですが両方を一致させることはできませんか?)元のポイントについては、繰り返しますが、より柔軟性を提供しながら、コマンドの機能を実行します。POSIX準拠になるように再構成することもできます。*@find . -type f -perm +a=xmdfind
mklement0 2015年

1

簡単な答えは、「実行可能ファイルはPATH変数に含まれるディレクトリにあります」ですが、実際には実行可能ファイルが見つからず、多くの実行可能ファイルが見落とされる可能性があります。

Macについてはあまり知りませんが、 "mdfind 'kMDItemContentType = public.unix-executable'"は解釈されたスクリプトなどを見逃す可能性があると思います

(実際に実行可能であるかどうかに関係なく)実行可能ビットが設定されたファイルを検索しても問題ない場合は、問題ありません。

find . -type f -perm +111 -print

サポートされている場合、「-executable」オプションを使用すると、ACLやその他の権限のアーティファクトをさらにフィルターで確認できますが、技術的には「-pemr +111」とそれほど変わりません。

将来的には、findが「-magic」をサポートし、特定のマジックIDを持つファイルを明示的に検索できるようになるかもしれませんが、すべての実行可能形式のマジックIDを細かく指定する必要があります。

私はunixで技術的に正しい簡単な方法を知らない。


1

したがって、実行権限のあるファイルだけでなく、実行可能ファイルのタイプ(スクリプト、ELFバイナリなど)を実際に検索したい場合は、おそらくこのようなことを実行する必要があります(現在のディレクトリ。必要なディレクトリ):

 gfind . -type f -exec bash -c '[[ $(file -b "'{}'") == *" executable "* ]] ' \; -print

または、macports(linuxユーザー)を使用していないか、必要に応じてgnu findをインストールしてください。

 find . -type f -exec bash -c '[[ $(file -b "'{}'") == *" executable "* ]] ' \; -print

OS Xを使用している場合は、is_execと呼ばれるどこかに隠された小さなユーティリティが付属していますが、基本的にはその小さなテストをバンドルしているので、コマンドラインを見つけた場合は短くすることができます。ただし、この方法は、==テストを=〜テストに簡単に置き換えて、実行可能なプレーンテキストファイルや、ファイルコマンドが返すその他の情報などのより複雑なプロパティをチェックするために、より柔軟です。


ここでの引用の正確なルールはかなり不透明なので、試行錯誤でそれを解決するだけですが、正しい説明を聞きたいです。


0

私は同じ問題を抱えており、その答えはdmenuソースコードにありました。その目的のために作成されたstestユーティリティです。「stest.c」および「arg.h」ファイルをコンパイルできます。これは動作するはずです。使い方のmanページがあり、私はそこに便宜上ここに置いています。

STEST(1)         General Commands Manual         STEST(1)

NAME
       stest - filter a list of files by properties

SYNOPSIS
       stest  [-abcdefghlpqrsuwx]  [-n  file]  [-o  file]
       [file...]

DESCRIPTION
       stest takes a list of files  and  filters  by  the
       files'  properties,  analogous  to test(1).  Files
       which pass all tests are printed to stdout. If  no
       files are given, stest reads files from stdin.

OPTIONS
       -a     Test hidden files.

       -b     Test that files are block specials.

       -c     Test that files are character specials.

       -d     Test that files are directories.

       -e     Test that files exist.

       -f     Test that files are regular files.

       -g     Test  that  files  have  their set-group-ID
              flag set.

       -h     Test that files are symbolic links.

       -l     Test the contents of a directory  given  as
              an argument.

       -n file
              Test that files are newer than file.

       -o file
              Test that files are older than file.

       -p     Test that files are named pipes.

       -q     No  files are printed, only the exit status
              is returned.

       -r     Test that files are readable.

       -s     Test that files are not empty.

       -u     Test that files have their set-user-ID flag
              set.

       -v     Invert  the  sense  of  tests, only failing
              files pass.

       -w     Test that files are writable.

       -x     Test that files are executable.

EXIT STATUS
       0      At least one file passed all tests.

       1      No files passed all tests.

       2      An error occurred.

SEE ALSO
       dmenu(1), test(1)

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