Bashの$ PATHからすべての実行可能ファイルをリストするワンライナーはありますか?.
これは答えではありませんが、実行できるコマンドであるバイナリを表示しています
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.
Zshの場合:
whence -pm '*'
または:
print -rl -- $commands
($PATH
の複数のコンポーネントに現れるコマンドについては、最初のコマンドのみがリストされることに注意してください)。
フルパスなしのコマンドが必要で、適切な方法で並べ替える場合:
print -rl -- ${(ko)commands}
(つまり、値の代わりにその連想配列のキーを取得します)。
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
これはドットファイルをスキップします。それらが必要な場合は、-A
フラグをls
に追加します(もしあなたが持っている場合、またはPOSIXを使いたい場合:ls -aH $PATH | grep -Fxv -e . -e ..
私はこれを思いつきました:
IFS=':';for i in $PATH; do test -d "$i" && find "$i" -maxdepth 1 -executable -type f -exec basename {} \;; done
[〜#〜] edit [〜#〜]:これは、Apacheユーザーがbinディレクトリのファイルの一部を読み取っているときにSELinuxアラートをトリガーしない唯一のコマンドのようです。
これはどう
find ${PATH//:/ } -maxdepth 1 -executable
文字列置換はBashで使用されます。
シェルで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'関数を使用せずにpythonコードの1行を使用して実行できるかどうかを確認するための、私にとってはほとんど楽しい練習でした。より読みやすい形式で、いくつかのコメントを付けて、コードは次のようになります。
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)) ])
#!/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