現在のPATH内のすべてのファイル/実行可能バイナリを一覧表示するための「ls -la」スタイルのコマンドを実行する「簡単な」方法はありますか?
(私は出力をgrepにパイプして、プレフィックスは不明であるが基本的には「名前」がわかっているコマンドを探すために、bashのオートコンプリート/タブ移動が本質的に役に立たない場合の種類です。したがって、ある種の「逆オート完全な機能」...)
現在のPATH内のすべてのファイル/実行可能バイナリを一覧表示するための「ls -la」スタイルのコマンドを実行する「簡単な」方法はありますか?
(私は出力をgrepにパイプして、プレフィックスは不明であるが基本的には「名前」がわかっているコマンドを探すために、bashのオートコンプリート/タブ移動が本質的に役に立たない場合の種類です。したがって、ある種の「逆オート完全な機能」...)
回答:
compgen -c # will list all the commands you could run.
compgen -a # will list all the aliases you could run.
compgen -b # will list all the built-ins you could run.
compgen -k # will list all the keywords you could run.
compgen -A function # will list all the functions you could run.
compgen -A function -abck # will list all the above in one go.
which $(compgen -A function -abck)
ますか?
以下は、ディレクトリの内容をリストする関数です$PATH
。引数が渡された場合、関数は、名前が引数の1つを含むコマンドのみをリストします。引数はグロブパターンとして解釈されます。
shopt -s extglob
lspath () {
local IFS pattern
IFS='|'
pattern="*@($*)*"
IFS=':'
for d in $PATH; do
for x in "$d/"$pattern; do
[ "$x" = "$d/$pattern" ] || echo "${x##*/}"
done
done | sort -u
}
多くのことと同様に、これはzshでは簡単です。
lspath () {
(($#)) || set ''
print -lr -- $^path/*$^@*(N:t) | sort -u
}
^
文字パラメータ展開は、各配列要素に追加される配列、例えばテキストと連結させるpath=(/bin /usr/bin); echo $^path/foo
プリントを/bin/foo /usr/bin/foo
。
/*$^@*
コミックの侮辱のように見えますが、実際には普通のキャラクター/
、ワイルドカード*
、修飾子$@
付きの特別なパラメーター(位置パラメーターの配列)^
、そして*
です。一致がない場合に空の展開を取得するため
(N:t)
のglob修飾子で N
あり、各修飾 t
のベース名(「末尾」)のみを保持するための履歴修飾子が続きます。
より不可解で、外部呼び出しを回避しますが、これは表面的な関心のみです。
lspath () {
(($#)) || set ''
local names; names=($^path/*$^@*(N:t))
print -lr -- ${(ou)names}
}
実際にapropos
は、短い説明にキーワードが含まれているコマンドのmanページを検索するコマンドを探している可能性があります。これは、manページがあるコマンドのみを検索するという制限です。
^
は「引数なし」の呼び出しに対して何も出力しないように見えますか?ドロップした場合、それらすべてをリストして、単一のキーワードを検索できます(ただし、それらのリストは検索できません)。(Non:t)
アスタリスクは拡大すべきであると言っているようですか?最後の1つを理解できませんでした。
path
が、シェルで実行すると、実際には$ PATHですが、ではなくスペースが含まれています:
。残りは非常に明確です:)
$path
はzsh機能です。これは、tieパラメータであり、更新時に自動的に更新される配列でPATH
、その逆も同様です。
function findinpath () {
OLDIFS="$IFS" ;
IFS="$(printf ':\t\n')" ;
for regexp in "$@" ; do
for adir in $PATH ; do
find "$adir" -perm -111 -a ! -type d -ls 2>/dev/null | grep -i "/[^/]*$regexp"
done ;
done ;
IFS="$OLDIFS" ;
}
検索は次のものとのみ一致します。少なくとも1つの "x"(実行可能)ビットセットがあり、それはディレクトリではありません。
見つけられる正規表現のリストでそれを使用します:
findinpath awk sed '\.sh$'
echo $PATH | tr ':' '\n' | sort | uniq -d
for i in $(echo $PATH | sed -e 's/\:/\ /g'); do find "$i" -perm +rwx -exec echo {} \; 2> /dev/null; done
まず$PATH
、sed にエコーし、 ":"を ""に置き換えます。
次に、それらのそれぞれについて検索を実行して、rwxでファイルを検索し、それらをエコーします。
2> /dev/null
ですので、find
エラーを印刷しません
-maxdepth 1
と-type f
あなたの検索では、他のあなたは(検索ではないであろうPATH)のサブディレクトリとそのファイルを見つけることができます。また、あなたの許可テストは奇妙です—のためだけにすべき+x
ですか?
:/bin
か/bin::/usr/bin
。コマンドに追加s/::/:.:/;s/^:/.:/;s/:$/:./
してみてくださいsed
。
find
はより多くのパスを検索できるので、ループなしで実行できます。find $(echo $PATH | sed -e 's/\:/\ /g') -perm +rwx …
もちろん、スペースを含むディレクトリ名はめちゃくちゃになりますが、ループベースのパスでも同じ問題が発生します。
for
ます。したがってfor
、4ワードのリストをループします。単語分割を操作するIFS
には、必要に応じてを設定しますIFS=':'; find $PATH -perm +rwx …
。
ls -la
?