Enumerar todos los comandos que conoce un shell

32

¿Qué puedo escribir en mi shell (que resulta ser bash) que enumerará todos los comandos que se reconocen?

Además, ¿esto difiere según el shell? ¿O todos los shells solo tienen un "directorio" de comandos que reconocen?

En segundo lugar, una pregunta diferente, pero ¿cómo puedo anular cualquiera de esos? En otras palabras, ¿cómo puedo escribir mi propio viewcomando para reemplazar el existente en mi sistema Ubuntu, que parece cargarse vim?

el espejo
fuente
55
Por favor no combine preguntas. Publique cada una como una pregunta separada.
terdon
Casi duplicado de unix.stackexchange.com/q/63073/135943 (He vinculado en ambas direcciones.)
Comodín el

Respuestas:

61

Puedes usarcompgen

compgen -c # will list all the commands you could run.

FYI:

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.
Rahul Patil
fuente
44
Tenga en cuenta que compgen -cincluirá cosas como {o whileque no son estrictamente comandos.
Stéphane Chazelas
13

Un shell conoce cuatro tipos de comandos.

  • Alias: estos son apodos para un comando con algunas opciones. Se definen en el archivo de inicialización del shell ( ~/.bashrcpara bash).
  • Funciones: son fragmentos de código de shell con un nombre. Al igual que los alias, se definen en el archivo de inicialización del shell.
  • Construidos: el shell viene con una pequeña cantidad de comandos incorporados. La mayoría de los componentes internos manipulan el estado del shell ( cdcambia el directorio actual, setcambia las opciones y los parámetros posicionales, exportcambia el entorno, ...). La mayoría de los shell ofrecen en gran medida los mismos componentes incorporados, pero cada shell tiene algunas extensiones del conjunto básico.
  • Comandos externos: son independientes del shell. Al igual que otros programas, el shell ejecuta programas externos buscándolos en la ruta de búsqueda ejecutable . La PATHvariable de entorno contiene una lista de directorios separados por dos puntos para buscar programas.

En caso de que haya comandos de varios tipos con el mismo nombre, se ejecuta la primera coincidencia en el orden anterior¹.

Puede ver a qué tipo de comando corresponde un nombre ejecutando type some_name.

Puede enumerar los alias ejecutando el aliasincorporado sin argumento. No hay forma de enumerar funciones o funciones que funcionen en todos los shells. Puede encontrar una lista de incorporados en la documentación del shell.

En bash, la setlista integrada de funciones con sus definiciones, así como las variables. En bash, ksh o zsh, typeset -fenumera las funciones con sus definiciones. En bash, puede enumerar todos los nombres de comandos de cualquier tipo con compgen -c. Puede usar compgen -A alias, compgen -A builtin compgen -A functionpara enumerar comandos de un tipo específico. Puede pasar una cadena adicional a compgenpara enumerar solo los comandos que comienzan con ese prefijo.

En zsh, puede listar los comandos disponibles en la actualidad de un tipo dado con echo ${(k)aliases}, echo ${(k)functions}, echo ${(k)builtins}y echo ${(k)commands}(esto último se enumeran los comandos externos solamente).

El siguiente fragmento agnóstico de shell enumera todos los programas externos disponibles:

case "$PATH" in
  (*[!:]:) PATH="$PATH:" ;;
esac

set -f; IFS=:
for dir in $PATH; do
  set +f
  [ -z "$dir" ] && dir="."
  for file in "$dir"/*; do
    if [ -x "$file" ] && ! [ -d "$file" ]; then
      printf '%s = %s\n' "${file##*/}" "$file"
    fi
  done
done

Hay un caso límite en Bash: comandos hash.

El Manual de referencia de Bash dice:

Se realiza una búsqueda completa de los directorios en $ PATH solo si el comando no se encuentra en la tabla hash

Tratar:

set -h
mkdir ~/dir-for-wat-command
echo 'echo WAT!' >~/dir-for-wat-command/wat
chmod +x ~/dir-for-wat-command/wat
hash -p ~/dir-for-wat-command/wat wat
wat

La PATHvariable de entorno no contiene ~/dir-for-wat-command, compgen -cno se muestra wat, pero puede ejecutarse wat.

Si desea sombrear un comando existente, defina un alias o una función .

¹ Excepción: algunas funciones incorporadas (llamadas incorporadas especiales ) no pueden ser sombreadas por una función; sin embargo, bash y zsh no cumplen con POSIX en ese punto en su modo predeterminado.

Gilles 'SO- deja de ser malvado'
fuente
Otro caso extremo es para valores de $PATHlike /bin:/usr/bin:(final :), donde fallaría al enumerar los archivos ejecutables en el directorio actual.
Stéphane Chazelas
3

La lista de comandos consta de dos conjuntos:

  1. Los comandos integrados en el shell
  2. Los comandos en tu PATH

No puede cambiar las funciones incorporadas, pero puede evitar que el shell use una función incorporada especificando el nombre de ruta completo como /bin/echo.

En cuanto a los comandos en su PATH, puede cambiar eso. PATHes una lista de directorios separados por dos puntos para buscar comandos. El primer archivo coincidente encontrado "gana".

export PATH=~/bin:${PATH}

(Esta sintaxis no funciona para csh shells derivados, sino todos los demás que conozco).

Eso se exporta PATHcon ~/binla primera entrada seguida del resto de las PATHentradas existentes . Entonces, su shell verificará directory calledbin in your home directory for a command *first* before checking the standardPATH` el sistema configurado. Puede hacer que compruebe el nuevo directorio al final usando en su lugar:

export PATH=${PATH}:~/bin

Para que PATHpersista en futuros inicios de sesión, agréguelo a uno .profileu otro archivo rc de shell.

kurtm
fuente
2

Prueba esto, usando :

printf '%s\n' ${PATH//:/\/* }
Gilles Quenot
fuente
1

Si presiona la tecla tab dos veces y luego y, obtendrá la lista de todos los comandos disponibles en su shell actual. Para la segunda pregunta, creo que deberías usar alias: shell alias .

taza de cafe
fuente
con respecto al alias, ¿es esa una forma infalible de anular y anular ("desalineando") un comando cuando se llama a cualquier parte del sistema (por ejemplo, desde un script de shell)?
themirror
1
¿Qué caparazón usas? No puedo obtener la doble pestaña para enumerar todos los comandos en mi bash.
terdon
Yo uso bash en Ubuntu 13.04. También hay un comando llamado compgen que se puede usar para obtener la lista de todos los comandos disponibles en el bash.
coffeMug
@terdon ¿Tiene instalado bash complete?
coffeMug
1
configurar show-all-if-ambiguous off
coffeMug