特定のディレクトリを除くすべての実行可能ファイルを検索する

特定のディレクトリを除くすべての実行可能ファイルを検索する

私は私ではないものを探しています$PATH

現在私はこれをしています

find / \( -path "/opt" -prune -o -path "/var" -prune -o -path "/bin" -prune -o -path "/sbin" -prune -o -path "/usr" -prune -o -path "/opt" \) -o -type f -executable -exec file {} \;

IFS=:より良い方法があると思います。 forループを使用して複数の部分を分離しようとしましたが、PATH正しく機能しませんでした。

編集:これにスクリプトを使用したくないと指定する必要があります。

答え1

GNUfindbash(質問で使用されている)シェルを想定すると、以下は望ましいタスクを実行する短いスクリプトです。

#!/bin/bash

IFS=:
set -f

args=( -false )
for dirpath in $PATH; do
        args+=( -o -path "$dirpath" )
done

find / \( \( "${args[@]}" \) -o \
          \( -type d \( ! -executable -o ! -readable \) \) \) -prune -o \
    -type f -executable -exec file {} +

argsまず、動的に設定されたパラメータを含む配列を作成しますfind。コロンで値(変数に割り当てた値)を分割して$PATHこれを行いますIFS$PATHループヘッダに引用されていないコンテンツを使用すると、分割が発生します。

通常、シェルは分割によって生成された単語ごとにファイル名globbingを呼び出します$PATHが、set -fディレクトリパスにワイルドカード文字が含まれている場合に備えてファイル名globbingを使用しました(オペランドはこれをパターンとして解釈している$PATHため、まだ問題があります。 )。-pathfind

私のPATH変数に文字列が含まれている場合

/usr/bin:/bin:/usr/sbin:/sbin:/usr/X11R6/bin:/usr/local/bin:/usr/local/sbin

これにより、args次のリストが表示されます(ここの各行は配列の別の要素であり、実際には中間に改行文字を含む文字列のセットではありません)。

-false
-o
-path
/usr/bin
-o
-path
/bin
-o
-path
/usr/sbin
-o
-path
/sbin
-o
-path
/usr/X11R6/bin
-o
-path
/usr/local/bin
-o
-path
/usr/local/sbin

リストはfind括弧で囲まれ、コマンド呼び出しに挿入されます。-prune上記のように一度だけ使用すればよいので、各ディレクトリに対して繰り返す必要はありません。

実行不可能または読めないディレクトリを削除することにしました。これにより、コンテンツにアクセスしたりリストしたりできないディレクトリに対する多くの権限エラーが排除されます。findこのビットを削除してコマンドを単純化するには、次のようにします。

find / \( "${args[@]}" \) -prune -o \
    -type f -executable -exec file {} +

また、file各パス名を一度実行するのではなく、見つかったパス名を一括して実行します。

答え2

これにより、zsh次のことができます。

set -o extendedglob
LC_ALL=C find / -regextype egrep \
  -regex ${(j[|])${(u)path:P}//(#m)[][.\$^*()+{}\\|.]/\\$MATCH} -prune -o \
  -type f -executable -exec file {} +
  • $path特別な配置です$PATH環境変数に。
  • $path:P各メンバーの実際のパスを取得します(絶対、標準、シンボリックリンクされていません)。
  • ${(u)array}重複排除(正規化後)
  • ${array//(#m)pattern/\\$MATCH}\一致するものの前にを追加しますpattern(ここにはすべてのegrep正規表現演算子があります)。
  • ${(j[|])array}配列の要素を連結して正規表現を|取得します。/dir|/dir\.2|...

関連情報