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 (
~/.bashrc
para 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 (
cd
cambia el directorio actual, set
cambia las opciones y los parámetros posicionales, export
cambia 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
PATH
variable 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 alias
incorporado 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 set
lista integrada de funciones con sus definiciones, así como las variables. En bash, ksh o zsh, typeset -f
enumera 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 function
para enumerar comandos de un tipo específico. Puede pasar una cadena adicional a compgen
para 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 PATH
variable de entorno no contiene ~/dir-for-wat-command
, compgen -c
no 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.