Listar todos los archivos / binarios en la RUTA actual


10

¿Existe una forma "fácil" de ejecutar un comando de estilo "ls -la" para enumerar todos los archivos / binarios ejecutables en la RUTA actual?

(Tengo la intención de canalizar la salida en grep, para buscar comandos con prefijos desconocidos pero básicamente "nombres" conocidos, el tipo de caso en el que la finalización automática / tabulación en bash es esencialmente inútil. Por lo tanto, algún tipo de "auto inverso" característica completa "...)


¿Puedes dar ejemplos? ¿Cómo será diferente con ls -la?
John Siu

"ls -la" / "ls -a" solo enumera los archivos en su directorio actual (pwd). Quiero enumerar todos los archivos (ejecutables) en todos los directorios incluidos en PATH.
sme

Respuestas:


19
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. 

Bien, esto es mucho lo que he estado buscando. Incluso incluye binarios ejecutables en el directorio actual. Gracias.
sme

Funciona bien ... en bash.
Emanuel Berg

¿Hay alguna manera de enumerar el camino de cada uno de estos sin hacer which $(compgen -A function -abck)?
h3rrmiller

No pude encontrar ninguna alternativa mejor.
Nykakin

3

Aquí hay una función que enumera el contenido de los directorios $PATH. Si pasa argumentos, la función solo enumera los comandos cuyo nombre contiene uno de los argumentos. Los argumentos se interpretan como patrones globales.

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 muchas cosas, esto es más fácil en zsh.

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

El ^carácter en la expansión de parámetros hace que el texto concatenado con la matriz se agregue a cada elemento de la matriz, por ejemplo, path=(/bin /usr/bin); echo $^path/fooimpresiones /bin/foo /usr/bin/foo.
/*$^@*parece un insulto al cómic, pero de hecho es el personaje ordinario /, el comodín *, el parámetro especial $@(la matriz de parámetros posicionales) con el ^modificador, y de nuevo *.
(N:t)es el calificador global N para obtener una expansión vacía si no hay una coincidencia seguida por el modificador de historial t para mantener solo el nombre base ("cola") de cada coincidencia.

Más críptico, evita la llamada externa, pero esto es solo de interés cosmético:

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

De hecho, puede estar buscando el aproposcomando, que busca páginas del comando man cuya descripción breve contiene una palabra clave. Una limitación es que esto solo encuentra comandos que tienen una página de manual.


En la función zsh, ¿el segundo ^parece no generar salida para una llamada "sin argumentos"? Si lo suelta, puede enumerarlos a todos y aún buscar palabras clave individuales (pero no una lista de ellas). El (Non:t)parece decir que los asteriscos deberían expandirse? No pude resolver ese último.
Emanuel Berg

@EmanuelBerg Correcto, gracias por la solución. He agregado una explicación del ruido de la línea.
Gilles 'SO- deja de ser malvado'

Bien, veamos: si no hay argumentos, los "pone" a nada, porque lo que estaba allí (cuando no había ninguno), ¿de alguna manera era perjudicial para lo que hizo después? Además, nunca he visto minúsculas path, pero cuando lo ejecuto en el shell, de hecho es $ PATH pero con espacios en lugar de :. El resto es claro como el cristal :)
Emanuel Berg

@EmanuelBerg No: si no hay argumentos, configuro la matriz de argumentos para que sea una matriz de un elemento que contenga la cadena vacía. De esta forma, sin argumentos significa que cada nombre que contiene la cadena vacía coincide, es decir, cada nombre coincide. $pathes una característica de zsh: es un parámetro vinculado , una matriz que se actualiza automáticamente cuando PATHse actualiza y viceversa.
Gilles 'SO- deja de ser malvado'

¡Ajá, ahora veo! ¡Guau, eso no era ortodoxo!
Emanuel Berg

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" ; 
}

el find solo coincide con eso: tiene al menos un conjunto de bits "x" (ejecutable), y ese no es un directorio.

y úsalo con una lista de expresiones regulares que encontrarás:

findinpath awk sed '\.sh$'

regexp "." te mostrará todo
Olivier Dulac

con el IFS regular, puede encontrar entradas duplicadas en su $ PATH con:echo $PATH | tr ':' '\n' | sort | uniq -d
Olivier Dulac

1
Probé el código para todas las respuestas y este es el único que realmente me dio lo que estaba buscando (rutas completas a cada instancia de un comando dado en la RUTA).
Chris Page

Me alegra que haya ayudado :)
Olivier Dulac

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

primero hacemos eco $PATHen sed y reemplazamos ":" con "".

luego hacemos una búsqueda en cada una de esas cosas para encontrar archivos con rwx y hacerles eco.

2> /dev/nulles así findque no imprime errores


3
necesita un -maxdepth 1y -type fen su búsqueda, de lo contrario encontrará subdirectorios y sus archivos (que la búsqueda de RUTA no lo hará). Además, su prueba de permiso es extraña, ¿debería ser +x, creo?
derobert el

Esto no manejará los casos extremos si una entrada en blanco válida es igual a '.', Por ejemplo :/bino /bin::/usr/bin. Intenta agregar s/::/:.:/;s/^:/.:/;s/:$/:./al sedcomando.
Arcege

En realidad, findpuede buscar más rutas, por lo que puede hacerlo sin el bucle: por find $(echo $PATH | sed -e 's/\:/\ /g') -perm +rwx …supuesto, los nombres de directorio que contienen espacios lo estropearán, pero el bucle basado tiene el mismo problema de todos modos.
manatwork

@manatwork tienes razón.
Agregué

Lo siento, eso no resuelve nada. El problema es reemplazar los dos puntos con espacios para permitir la división de palabras. Entonces transforma "/ foo bar: / fiz baz" en "/ foo bar / fiz baz" y luego pasa eso a for. Entonces forrecorrerá una lista de 4 palabras. Para manipular la división de palabras mejor establecer el IFSacuerdo a su necesidad: IFS=':'; find $PATH -perm +rwx ….
manatwork
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.