$ PATHからすべてのバイナリをリストします


30

bashの$ PATHからすべての実行可能ファイルをリストする1つのライナーがあります。

回答:


38

これは答えではありませんが、実行可能なコマンドであるバイナリを表示しています

compgen -c

(想定bash

その他の便利なコマンド

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.

1
このコマンドを知っているのは良いことで、実際に実行するには実行可能ファイルが必要です。たぶん私はこのコマンドを代わりに使用します。
jcubic

それはまた、組み込みコマンド、関数、キーワード(のような含まれていることに注意してくださいin{...)とエイリアスを。
ステファンシャゼル14年

私はこのサイトで見つけた前卿は、私は長い時間で、私は私のドラフトに保存されていた。..更新しました...
ラーフルパティル

@jcubic、シェルはコマンド完了のために既にそれをしていますなぜそれを手で行うのですか?
フォンブランド14年

@vonbrand私はjavascript / phpのシェルで作業しており、非対話モードでシェルを実行しています。
jcubic

15

zshの場合:

whence -pm '*'

または:

print -rl -- $commands

(の複数のコンポーネントに表示されるコマンドの$PATH場合、最初のコンポーネントのみがリストされることに注意してください)。

完全なパスを使用せずに、適切な尺度でソートされたコマンドが必要な場合:

print -rl -- ${(ko)commands}

(つまり、値ではなく連想配列のキーを取得します)。


bashを使用していることは言及しませんでした。
jcubic

5

POSIXシェルでは、最終的な並べ替えを除き、外部コマンドを使用せず(にprintfフォールバックしない場合は組み込みであるechoと想定)、実行可能ファイル名に改行が含まれていないことを前提とします。

{ set -f; IFS=:; for d in $PATH; do set +f; [ -n "$d" ] || d=.; for f in "$d"/.[!.]* "$d"/..?* "$d"/*; do [ -f "$f" ] && [ -x "$f" ] && printf '%s\n' "${x##*/}"; done; done; } | sort

$PATH.代わりに使用する)に空のコンポーネントがなく-、で始まるコンポーネントがなく\[?*、PATHコンポーネントまたは実行可能ファイル名にワイルドカード文字がなく、で始まる実行可能ファイルがない.場合、これを単純化できます:

{ IFS=:; for d in $PATH; do for f in $d/*; do [ -f $f ] && [ -x $f ] && echo ${x##*/}; done; done; } | sort

POSIX findとを使用してsed

{ IFS=:; set -f; find -H $PATH -prune -type f -perm -100 -print; } | sed 's!.*/!!' | sort

パスにまれな非実行可能ファイルまたは非正規ファイルをリストする場合は、はるかに簡単な方法があります。

{ IFS=:; ls -H $PATH; } | sort

これはドットファイルをスキップします。あなたがそれらを必要とするならば、あなたのものがそれを持っているならば、またはあなたがPOSIXに固執したいならば、に-Aフラグを加えてlsください:ls -aH $PATH | grep -Fxv -e . -e ..

bashおよびzshには、より単純なソリューションがあります。


これは、それ$PATHが設定され、空のコンポーネントが含まれておらず、そのコンポーネントが検索条件(またはlsオプション)のように見えないことを前提としています。それらのいくつかは、ドットファイルも無視します。
ステファンシャゼル

@StephaneChazelasうん。空のコンポーネントは別として、これは「これをしない」カテゴリに完全に該当します。PATHは管理下にあります。
ジル 'SO-悪であるのをやめる' 14年

空の要素が最後の場合(通常どおり)、まだ機能しません。(shエミュレーション内yashおよびzshshエミュレーションを除く)。
ステファンシャゼル14年

あなたの中にfind-pruneディレクトリを一覧表示できなくなります。シンボリックリンク(実行可能ファイルに共通)を含めるのでは-Lなく、おそらく必要です-H-perm -100ファイルがユーザーによって実行可能であることを保証するものではありません(実行可能ファイルを除外する可能性はほとんどありません)。
ステファンシャゼル14年

4

私はこれを思いつきました:

IFS=':';for i in $PATH; do test -d "$i" && find "$i" -maxdepth 1 -executable -type f -exec basename {} \;; done

編集:これは、Apacheユーザーがbinディレクトリ内のファイルの一部を読み取り中にSELinuxアラートをトリガーしない唯一のコマンドのようです。


5
なぜforIFS=:; find $PATH -maxdepth 1 -executable -type f -printf '%f\n'
マナトワーク14年

@manatworkは、存在しないパスに対して機能しますか?
jcubic

@manatworkは、それができることを知りませんでした。IFSについてさらに読む必要があります。
jcubic

3
これは、$PATHが設定され、ワイルドカード文字が含まれておらず、空のコンポーネントが含まれていないことを前提としています。また、GNUによるの実装も想定していますfind
ステファンシャゼル14年

2
-type f(GNU固有)の代わりに、-xtype fシンボリックリンクも省略します。また、$PATHシンボリックリンクであるコンポーネントのコンテンツもリストされません。
ステファンシャゼル14年

3

これはどう

find ${PATH//:/ } -maxdepth 1 -executable

文字列置換はBashで使用されます。


3
これは、$PATHが設定されていること、ワイルドカードや空白文字が含まれていないこと、空のコンポーネントが含まれていないことを前提としています。GNU findも同様です。これ${var//x/y}ksh構文であることに注意してください(zshおよびbashでもサポートされています)。厳密に言えば、$ PATHコンポーネントもfind述語ではないことを前提としています。
ステファンシャゼル14年

1
また、$PATHコンポーネントはシンボリックリンクではないと想定しています。
ステファンシャゼル14年

@StephaneChazelas:ありがとう!言い換えれば、通常の場合。

設定IFS=:は、この置換を行うよりも堅牢です。Windowsでは、スペースを含むパスはそれほど珍しくありません。シンボリックリンクはかなり一般的ですが、それはで簡単に解決でき-Hます。
ジル 'SO-悪であるのをやめる' 14年

@Gilles:もちろんです。ただし、この質問の合理的な使用例は見当たらないため、防弾回答は必要ありません。

1

シェルでpythonを実行できる場合は、次の(途方もなく長い)ワンライナーも使用できます。

python -c 'import os;import sys;output = lambda(x) : sys.stdout.write(x + "\n"); paths = os.environ["PATH"].split(":") ; listdir = lambda(p) : os.listdir(p) if os.path.isdir(p) else [ ] ; isfile = lambda(x) : True if os.path.isfile(os.path.join(x[0],x[1])) else False ; isexe = lambda(x) : True if os.access(os.path.join(x[0],x[1]), os.X_OK) else False ; map(output,[ os.path.join(p,f) for p in paths for f in listdir(p) if isfile((p,f)) and isexe((p,f)) ])'

これは主に、「exec」関数を使用せずに1行のpythonコードを使用して実行できるかどうかを確認するための楽しい練習でした。より読みやすい形式で、コメントを追加すると、コードは次のようになります。

import os
import sys

# This is just to have a function to output something on the screen.
# I'm using python 2.7 in which 'print' is not a function and cannot
# be used in the 'map' function.
output = lambda(x) : sys.stdout.write(x + "\n")

# Get a list of the components in the PATH environment variable. Will
# abort the program is PATH doesn't exist
paths = os.environ["PATH"].split(":")

# os.listdir raises an error is something is not a path so I'm creating
# a small function that only executes it if 'p' is a directory
listdir = lambda(p) : os.listdir(p) if os.path.isdir(p) else [ ]

# Checks if the path specified by x[0] and x[1] is a file
isfile = lambda(x) : True if os.path.isfile(os.path.join(x[0],x[1])) else False

# Checks if the path specified by x[0] and x[1] has the executable flag set
isexe = lambda(x) : True if os.access(os.path.join(x[0],x[1]), os.X_OK) else False

# Here, I'm using a list comprehension to build a list of all executable files
# in the PATH, and abusing the map function to write every name in the resulting
# list to the screen.
map(output, [ os.path.join(p,f) for p in paths for f in listdir(p) if isfile((p,f)) and isexe((p,f)) ])

0
#!/usr/bin/env python
import os
from os.path import expanduser, isdir, join, pathsep

def list_executables():
    paths = os.environ["PATH"].split(pathsep)
    executables = []
    for path in filter(isdir, paths):
        for file_ in os.listdir(path):
            if os.access(join(path, file_), os.X_OK):
                executables.append(file_)
    return executables
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.