特定の文字で始まるコマンドのPATH検索

特定の文字で始まるコマンドのPATH検索

文字で始まるすべてのコマンドを一覧表示するには、どのコマンドを使用できますかgbash完成機能が利用できないため、スクリプトを作成する必要があるとします。

答え1

デフォルトでは、リストされているすべてのディレクトリを繰り返し、PATHaを実行してfindパターンを検索する必要があります。この場合、文字で始まるバイナリです。「G」。速く走る:

for i in $(echo $PATH | tr ":" "\n")
do
  find ${i} -iname "g*" 2> /dev/null
done

一部のディレクトリには正規表現に一致するファイルがない可能性があるため2> /dev/null

このアプローチは、静的または動的ライブラリ検索などの他の多くの状況に役立ちます。

答え2

そこはい簡単なコマンドを使用してこれを実行できますが、「完了しない」要件にbash違反する可能性があります。bashそれにもかかわらず、私はこの答えの終わりにそれを含みます。代わりに、この問題を解決するためにいくつかのループを使用します。

g以下のディレクトリのうち、その文字で始まる実行可能な外部コマンドをすべて探したいとします$PATH

#!/bin/sh

IFS=:; set -f; set -- $PATH; set +f
for dirpath do
    for pathname in "$dirpath"/g*; do
        if [ -x "$pathname" ]; then
            printf 'Executable: %s (%s)\n' "${pathname##*/}" "$pathname"
        fi
    done
done

これは最初に位置引数を変数に格納されているディレクトリのリストに設定しますPATHIFSに設定してこれを行います:。つまり、引用符なしで使用すると、その値は文字列の文字単位に分割されます$PATH:引用符のない変数を安全に使用するために、文字列のset -f一部がファイル名のワイルドカードパターンとして解釈できる場合は、ワイルドカードを一時的に解放します。set +f後で必要になるため、ワイルドカードを再度有効にします。

場所パラメータをディレクトリパスのリストに設定したら、パラメータを繰り返します。各反復で、その文字で始まるディレクトリ内のすべてのファイルのパス名を取得し、各ファイルをテストしてg1)存在するか2)実行可能であることを確認します(テストは-xこれら2つのことを行います)。実行可能な場合は、その名前とフルパス名を出力します。

これは現在の状況のみを扱うように質問を制限することに注意してください$PATH。エイリアスやシェル機能は見つかりません。組み込みユーティリティとしてのみ提供されるユーティリティも考慮されません。

${variable//pattern/word}変数値のどこからでもパターンを文字列に置き換えることをfind理解するシェルを使用し-maxdepth-executableその点について賛辞を送ります)イサクこのアプローチは他の場所で言及されています。)

(
    set -f
    find -H -- ${PATH//:/ } -maxdepth 1 -type f -name 'g*' -executable
)

findこれにより、コマンドのワイルドカード機能がオフになり、リストされた各ディレクトリで実行可能ファイルに対応する名前$PATHで始まる名前が検索されます。g現在のユーザーだけが実行できることがわかります。-perm -o+x代わりに、-executable実行可能ビットが「その他」に設定されているかどうかをテストするために使用してください。

-Hこのオプションはfindコマンドライン(検索パスなど)で指定されたシンボリックリンクを確認しますが、パスをナビゲートしたときに見つかったシンボリックリンクは確認しません。


上記は一般的な/bin/sh解決策です。特別なコマンドが許可されている場合は、文字で始まるすべてのbash外部コマンド、シェル機能、およびエイリアスのリストを生成できます。g

compgen -c g

組み込みコマンドを含めるには、次のようにします。

compgen -bc g

...しかし、これは「bash使用に応じて完了」と見なすことができます。

compgen組み込みコマンドはマニュアルに記載されていますbash(1)

関連情報