Listar todos os arquivos / binários no PATH atual

11

Existe uma maneira "fácil" de executar um comando de estilo "ls -la" para listar todos os arquivos / binários executáveis no PATH atual?

(Eu pretendo enviar a saída para o grep, para procurar comandos com prefixos desconhecidos, mas basicamente "nomes" conhecidos, o tipo de caso em que o preenchimento automático / tabulação no bash é essencialmente inútil. Então, algum tipo de " recurso de autocompletar inverso "...)

    
por s-m-e 09.01.2013 / 18:55

4 respostas

20
compgen -c # will list all the commands you could run.
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. 
    
por 09.01.2013 / 21:23
3

Aqui está uma função que lista o conteúdo dos diretórios $PATH . Se passado argumentos, a função só lista comandos cujo nome contenha um dos argumentos. Os argumentos são interpretados como padrões glob.

shopt -s extglob
lspath () {
  local IFS pattern
  IFS='|'
  pattern="*@($*)*"
  IFS=':'
  for d in $PATH; do
    for x in "$d/"$pattern; do
      [ "$x" = "$d/$pattern" ] || echo "${x##*/}"
    done
  done | sort -u
}

Como muitas outras coisas, isso é mais fácil em zsh.

lspath () {
  (($#)) || set ''
  print -lr -- $^path/*$^@*(N:t) | sort -u
}

O caractere ^ na expansão de parâmetro faz com que o texto concatenado com a matriz para ser adicionado a cada elemento da matriz, por exemplo path=(/bin /usr/bin); echo $^path/foo imprime /bin/foo /usr/bin/foo .
/*$^@* parece um insulto de quadrinhos, mas na verdade é o caractere comum / , o caractere curinga * , o parâmetro especial $@ (a matriz do parâmetro posicional) com o modificador ^ e novamente * .
(N:t) é o glob qualificador N para obter uma expansão vazia se não houver correspondência seguida pelo modificador de histórico t para manter apenas o nome da base ("tail") de cada correspondência.

Mais enigmático, evita a chamada externa, mas isso é apenas de interesse cosmético:

lspath () {
  (($#)) || set ''
  local names; names=($^path/*$^@*(N:t))
  print -lr -- ${(ou)names}
}

Você pode, de fato, estar procurando o comando apropos , que pesquisa por páginas man de comandos cujo descrição curta contém uma palavra-chave. Uma limitação é que isso só encontra comandos que tenham uma página man.

    
por 10.01.2013 / 00:12
1
function findinpath () { 
   OLDIFS="$IFS" ; 
   IFS="$(printf ':\t\n')" ; 
   for regexp in "$@" ; do 
      for adir in $PATH ; do 
         find "$adir" -perm -111 -a ! -type d -ls 2>/dev/null | grep -i "/[^/]*$regexp"
      done ; 
   done ; 
   IFS="$OLDIFS" ; 
}

a localização corresponde apenas a: ter pelo menos um conjunto de bits "x" (executável), e isso não é um diretório.

e use-o com uma lista de expressões regulares a serem encontradas:

findinpath awk sed '\.sh$'
    
por 09.01.2013 / 19:16
1
for i in $(echo $PATH | sed -e 's/\:/\ /g'); do find "$i" -perm +rwx -exec echo {} \; 2> /dev/null; done

primeiro, fazemos echo de $PATH no sed e substituímos ":" por "".

em seguida, fazemos uma busca em cada uma dessas coisas para encontrar arquivos com rwx e ecoá-los.

2> /dev/null é, portanto, find não imprime erros

    
por 09.01.2013 / 19:03