Antworten:
Dies ist keine Antwort, sondern zeigt binär, einen Befehl, den Sie ausführen könnten
compgen -c
(vorausgesetzt bash
)
Andere nützliche Befehle
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
, {
...) und Aliase.
Mit zsh:
whence -pm '*'
Oder:
print -rl -- $commands
(Beachten Sie, dass bei Befehlen, die in mehr als einer Komponente von vorkommen $PATH
, nur die erste aufgeführt wird.)
Wenn Sie die Befehle ohne die vollständigen Pfade und nach guten Maßen sortiert haben möchten:
print -rl -- ${(ko)commands}
(Das heißt, erhalten Sie die Schlüssel dieses assoziativen Arrays anstelle der Werte).
In jeder POSIX-Shell, ohne einen externen Befehl zu verwenden (vorausgesetzt, es printf
ist eine Funktion integriert, auf die nicht zurückgegriffen wird echo
), mit Ausnahme der endgültigen Sortierung und unter der Annahme, dass kein ausführbarer Name eine neue Zeile enthält:
{ 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
Wenn Sie keine leere Komponente in $PATH
( .
stattdessen verwenden) oder Komponenten haben, die mit beginnen -
, oder Platzhalterzeichen \[?*
in PATH-Komponenten oder ausführbaren Namen und keine ausführbaren Dateien, die mit beginnen .
, können Sie dies folgendermaßen vereinfachen:
{ IFS=:; for d in $PATH; do for f in $d/*; do [ -f $f ] && [ -x $f ] && echo ${x##*/}; done; done; } | sort
Verwendung von POSIX find
und sed
:
{ IFS=:; set -f; find -H $PATH -prune -type f -perm -100 -print; } | sed 's!.*/!!' | sort
Wenn Sie bereit sind, die seltene nicht ausführbare Datei oder die nicht reguläre Datei im Pfad aufzulisten, gibt es einen viel einfacheren Weg:
{ IFS=:; ls -H $PATH; } | sort
Dadurch werden Punktdateien übersprungen. Wenn Sie sie brauchen, fügen Sie die -A
Flagge hinzu, ls
wenn Sie sie haben oder wenn Sie sich an POSIX halten möchten:ls -aH $PATH | grep -Fxv -e . -e ..
$PATH
das gesetzt ist und keine leeren Komponenten enthält und dass Komponenten nicht wie Prädikate (oder ls-Optionen) aussehen. Einige davon ignorieren auch Punktdateien.
yash
und zsh
in sh Emulation).
find
. -prune
verhindert das Auflisten von Verzeichnissen. Sie möchten wahrscheinlich -L
statt -H
wie Sie möchten Symlinks (gemeinsam für ausführbare Dateien) enthalten. -perm -100
gibt keine Garantie dafür, dass die Datei von Ihnen ausführbar ist (und möglicherweise (unwahrscheinlich) ausführbare Dateien ausschließt).
Das habe ich mir ausgedacht:
IFS=':';for i in $PATH; do test -d "$i" && find "$i" -maxdepth 1 -executable -type f -exec basename {} \;; done
BEARBEITEN : Es scheint, dass dies der einzige Befehl ist, der beim Lesen einiger Dateien im bin-Verzeichnis durch einen Apache-Benutzer keine SELinux-Warnung auslöst.
for
? IFS=:; find $PATH -maxdepth 1 -executable -type f -printf '%f\n'
$PATH
gesetzt ist und keine Platzhalterzeichen und keine leeren Komponenten enthält. Das setzt auch die GNU-Implementierung von vorausfind
.
-type f
anstelle von (GNU-spezifisch) -xtype f
werden auch Symlinks weggelassen. Dadurch wird auch nicht der Inhalt von $PATH
Komponenten aufgelistet, bei denen es sich um Symlinks handelt.
Wie wäre es damit
find ${PATH//:/ } -maxdepth 1 -executable
Die Zeichenfolgensubstitution wird mit Bash verwendet.
$PATH
gesetzt ist, keine Platzhalter oder Leerzeichen enthält, keine leeren Komponenten enthält. Das setzt voraus, dass GNU auch findet. Beachten Sie, dass dies ${var//x/y}
die ksh
Syntax ist (wird auch von zsh und bash unterstützt). Genau genommen setzt dies auch voraus, dass $ PATH-Komponenten auch keine find
Prädikate sind.
$PATH
Komponenten keine Symlinks sind.
IFS=:
ist robuster als diese Ersetzung. Pfade mit Leerzeichen sind unter Windows keine Seltenheit. Symbolische Verknüpfungen sind weit verbreitet, aber das lässt sich leicht lösen -H
.
Wenn Sie Python in Ihrer Shell ausführen können, kann auch der folgende (lächerlich lange) Einzeiler verwendet werden:
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)) ])'
Dies war für mich meistens eine lustige Übung, um herauszufinden, ob es mit einer einzigen Zeile Python-Code möglich ist, ohne die Funktion 'exec' zu verwenden. In einer besser lesbaren Form und mit einigen Kommentaren sieht der Code folgendermaßen aus:
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