Jawaban:
Ini bukan jawaban, tetapi ini menunjukkan biner, perintah yang bisa Anda jalankan
compgen -c
(dengan asumsi bash
)
Perintah lain yang bermanfaat
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.
in
, {
...) dan alias.
Dengan zsh:
whence -pm '*'
Atau:
print -rl -- $commands
(perhatikan bahwa untuk perintah yang muncul di lebih dari satu komponen $PATH
, mereka akan mendaftar hanya yang pertama).
Jika Anda ingin perintah tanpa jalur lengkap, dan diurutkan untuk mengukur:
print -rl -- ${(ko)commands}
(Yaitu, dapatkan kunci array asosiatif alih-alih nilai).
Dalam setiap shell POSIX, tanpa menggunakan perintah eksternal (dengan asumsi printf
dibangun di dalam, jika tidak kembali ke echo
) kecuali untuk pengurutan akhir, dan dengan asumsi bahwa tidak ada nama yang dapat dieksekusi berisi baris baru:
{ 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
Jika Anda tidak memiliki komponen kosong dalam $PATH
(gunakan .
saja) atau komponen yang dimulai dengan -
, atau karakter wildcard \[?*
dalam komponen PATH atau nama yang dapat dieksekusi, dan tidak ada yang dapat dijalankan yang dimulai dengan .
, Anda dapat menyederhanakan ini ke:
{ IFS=:; for d in $PATH; do for f in $d/*; do [ -f $f ] && [ -x $f ] && echo ${x##*/}; done; done; } | sort
Menggunakan POSIX find
dan sed
:
{ IFS=:; set -f; find -H $PATH -prune -type f -perm -100 -print; } | sed 's!.*/!!' | sort
Jika Anda bersedia untuk mencantumkan file langka yang tidak dapat dieksekusi atau file tidak biasa di jalur, ada cara yang lebih sederhana:
{ IFS=:; ls -H $PATH; } | sort
Ini melompati file dot; jika Anda membutuhkannya, tambahkan -A
bendera ke ls
jika Anda memilikinya, atau jika Anda ingin tetap berpegang pada POSIX:ls -aH $PATH | grep -Fxv -e . -e ..
$PATH
diatur dan tidak mengandung komponen kosong, dan bahwa komponen tidak terlihat seperti menemukan predikat (atau opsi ls). Beberapa dari mereka juga akan mengabaikan file dot.
yash
dan zsh
dalam emulasi sh).
find
satu Anda . -prune
akan mencegah daftar direktori. Anda mungkin ingin -L
bukan -H
karena Anda ingin menyertakan symlink (umum untuk executable). -perm -100
tidak memberikan jaminan bahwa file dapat dieksekusi oleh Anda (dan mungkin (tidak mungkin) mengecualikan file yang dapat dieksekusi).
Saya datang dengan ini:
IFS=':';for i in $PATH; do test -d "$i" && find "$i" -maxdepth 1 -executable -type f -exec basename {} \;; done
EDIT : Tampaknya ini adalah satu-satunya perintah yang tidak memicu peringatan SELinux saat membaca beberapa file di direktori bin oleh pengguna apache.
for
? IFS=:; find $PATH -maxdepth 1 -executable -type f -printf '%f\n'
$PATH
diatur dan tidak mengandung karakter wildcard dan tidak mengandung komponen kosong. Itu juga mengasumsikan implementasi GNU dari find
.
-type f
alih - alih (khusus GNU) -xtype f
, itu juga akan menghilangkan symlink. Itu juga tidak akan mencantumkan konten $PATH
komponen yang merupakan symlink.
Bagaimana dengan ini
find ${PATH//:/ } -maxdepth 1 -executable
Substitusi string digunakan dengan Bash.
$PATH
diatur, tidak mengandung karakter pengganti atau karakter kosong, tidak mengandung komponen kosong. Itu mengasumsikan menemukan GNU juga. Perhatikan bahwa ${var//x/y}
ini adalah ksh
sintaks (juga didukung oleh zsh dan bash). Tegasnya, itu juga mengasumsikan bahwa komponen $ PATH juga bukan find
predikat.
$PATH
komponen bukanlah symlink.
IFS=:
lebih kuat daripada melakukan substitusi ini. Jalur dengan spasi tidak biasa di Windows. Tautan simbolik cukup umum, tetapi mudah dipecahkan -H
.
Jika Anda dapat menjalankan python di shell Anda, maka satu-liner berikut (panjangnya ridiculously) dapat digunakan juga:
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)) ])'
Ini sebagian besar merupakan latihan yang menyenangkan bagi saya untuk melihat apakah itu dapat dilakukan dengan menggunakan satu baris kode python tanpa menggunakan fungsi 'exec'. Dalam bentuk yang lebih mudah dibaca, dan dengan beberapa komentar, kode ini terlihat seperti ini:
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