Risposte:
Questa non è una risposta, ma mostra binario, un comando che potresti eseguire
compgen -c
(supponendo bash
)
Altri comandi utili
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
, {
...) e alias.
Con zsh:
whence -pm '*'
O:
print -rl -- $commands
(nota che per i comandi che compaiono in più di un componente $PATH
, elencheranno solo il primo).
Se vuoi i comandi senza i percorsi completi e ordinati per buona misura:
print -rl -- ${(ko)commands}
(ovvero, ottenere le chiavi di quell'array associativo anziché i valori).
In qualsiasi shell POSIX, senza utilizzare alcun comando esterno (supponendo che printf
sia incorporato, se non ricadere in echo
), tranne per l'ordinamento finale e supponendo che nessun nome eseguibile contenga una nuova riga:
{ 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
Se non si dispone di alcun componente vuoto in $PATH
(utilizzare .
invece) né componenti che iniziano con -
, né caratteri jolly \[?*
in componenti PATH o nomi di eseguibili e nessun eseguibile che inizia con .
, è possibile semplificare questo per:
{ IFS=:; for d in $PATH; do for f in $d/*; do [ -f $f ] && [ -x $f ] && echo ${x##*/}; done; done; } | sort
Utilizzando POSIX find
e sed
:
{ IFS=:; set -f; find -H $PATH -prune -type f -perm -100 -print; } | sed 's!.*/!!' | sort
Se sei disposto a elencare il raro file non eseguibile o non regolare nel percorso, c'è un modo molto più semplice:
{ IFS=:; ls -H $PATH; } | sort
Questo salta i file punto; se ne hai bisogno, aggiungi la -A
bandiera a ls
se la tua ce l'ha, o se vuoi aderire a POSIX:ls -aH $PATH | grep -Fxv -e . -e ..
$PATH
sia impostato e che non contenga componenti vuoti e che i componenti non sembrano trovare predicati (o opzioni ls). Alcuni di questi ignoreranno anche i file di punti.
yash
e zsh
in emulazione sh).
find
. -prune
impedirà di elencare le directory. Probabilmente -L
invece di -H
come si desidera includere collegamenti simbolici (comune per gli eseguibili). -perm -100
non garantisce che il file sia eseguibile da te (e potrebbe (improbabile) escludere i file eseguibili).
Ho pensato a questo:
IFS=':';for i in $PATH; do test -d "$i" && find "$i" -maxdepth 1 -executable -type f -exec basename {} \;; done
EDIT : Sembra che questo sia l'unico comando che non attiva l'avviso SELinux durante la lettura di alcuni file nella directory bin dall'utente apache.
for
? IFS=:; find $PATH -maxdepth 1 -executable -type f -printf '%f\n'
$PATH
sia impostato e non contenga caratteri jolly e non contenga componenti vuoti. Ciò presuppone anche l'implementazione GNU di find
.
-type f
invece di (specifico GNU) -xtype f
, questo ometterà anche i collegamenti simbolici. Anche questo non elencherà il contenuto dei $PATH
componenti che sono collegamenti simbolici.
Cosa ne pensi di questo
find ${PATH//:/ } -maxdepth 1 -executable
La sostituzione di stringa viene utilizzata con Bash.
$PATH
sia impostato, non contenga caratteri jolly o caratteri vuoti, non contenga componenti vuoti. Ciò presuppone che anche GNU lo trovi. Si noti che ${var//x/y}
è la ksh
sintassi (supportata anche da zsh e bash). A rigor di termini, ciò presuppone anche che i componenti $ PATH non siano neanche find
predicati.
$PATH
componenti non siano collegamenti simbolici.
IFS=:
è più robusta rispetto a questa sostituzione. I percorsi con spazi non sono così rari su Windows. I collegamenti simbolici sono abbastanza comuni, ma è facilmente risolvibile -H
.
Se riesci a far funzionare Python nella tua shell, puoi usare anche la seguente linea (ridicolmente lunga):
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)) ])'
Questo è stato per lo più un esercizio divertente per me stesso per vedere se si potesse fare usando una riga di codice Python senza ricorrere all'utilizzo della funzione 'exec'. In una forma più leggibile e con alcuni commenti, il codice è simile al seguente:
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