文字で始まるすべてのコマンドを一覧表示するには、どのコマンドを使用できますかg
?bash
完成機能が利用できないため、スクリプトを作成する必要があるとします。
答え1
デフォルトでは、リストされているすべてのディレクトリを繰り返し、PATH
aを実行して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
これは最初に位置引数を変数に格納されているディレクトリのリストに設定しますPATH
。IFS
に設定してこれを行います:
。つまり、引用符なしで使用すると、その値は文字列の文字単位に分割されます$PATH
。:
引用符のない変数を安全に使用するために、文字列のset -f
一部がファイル名のワイルドカードパターンとして解釈できる場合は、ワイルドカードを一時的に解放します。set +f
後で必要になるため、ワイルドカードを再度有効にします。
場所パラメータをディレクトリパスのリストに設定したら、パラメータを繰り返します。各反復で、その文字で始まるディレクトリ内のすべてのファイルのパス名を取得し、各ファイルをテストしてg
1)存在するか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)
。