Linux / Comando / command: omitir funciones y comprobar comandos
command es un comando incorporado de shell que omite la búsqueda de funciones de shell y ejecuta comandos internos o comandos externos encontrados en PATH. Se usa principalmente cuando se crea una función envolvente con el mismo nombre para llamar al comando original o para verificar si el shell actual puede encontrar un comando en command -v.
En Bash, se verifica la información de interpretación de comandos con -v y -V, y -p usa la ruta de búsqueda predeterminada para encontrar utilidades estándar. exec, env y builtin tienen roles diferentes, por lo que se deben distinguir según el propósito.
¿Qué es el comando command?
Una función de shell puede tener el mismo nombre que un comando externo. En este caso, llamar al nombre tal cual dentro de la función puede resultar en una llamada recursiva a sí misma. Si se antepone command, se omite la función de shell con el mismo nombre y se selecciona el comando incorporado de Bash o un ejecutable encontrado en PATH.
command es un comando interno que proporcionan varios shells, incluido Bash. Su funcionamiento está definido en POSIX, aunque el texto de salida y las extensiones pueden variar entre implementaciones.
Sintaxis básica
command [-pVv] COMANDO [ARGUMENTOS...]
Si se utiliza sin opciones, ejecuta el comando especificado.
command ls -la
command printf '%s\n' 'hello'
En la mayoría de situaciones, parece que se ejecuta el comando directamente. La diferencia se revela cuando existe una función de shell con el mismo nombre.
Llamar al comando original dentro de una función de shell
Practique esta función en una subsesión de Bash abierta con bash. Antes de definirla, quite un posible alias de ese nombre en esa subsesión con unalias ls 2>/dev/null || true. La función muestra un mensaje y delega en command ls; --color=auto es una opción de GNU ls y debe adaptarse si utiliza otra implementación. Al terminar, exit cierra la subsesión y deja intactas las definiciones de la sesión anterior.
ls() {
printf '%s\n' 'Se muestra la lista.'
command ls --color=auto "$@"
}
Si escribe ls "$@" dentro de la función, se llamará nuevamente la misma función. command ls omite la búsqueda de función, por lo que se ejecutará un comando interno de Bash o un PATH externo de ls.
"$@" pasa los argumentos dados a la función manteniendo sus límites originales. Si los sustituye por $* o $@ sin comillas, los argumentos que incluyen espacios o comodines pueden romperse.
Verificar la existencia de un comando con command -v
-v imprime de forma concisa cómo se interpreta el nombre especificado en la shell actual. Devuelve un estado de éxito si encuentra el comando, y un estado de fallo si no lo encuentra, por lo que es útil para verificar la existencia en scripts.
command -v git
command -v cd
command -v printf
La salida puede ser la ruta del archivo ejecutable, así como la descripción de un comando interno, función o alias. Por lo tanto, no se debe asumir que el resultado es siempre la ruta del archivo.
if command -v curl >/dev/null 2>&1; then
printf '%s\n' 'curl está disponible.'
else
printf '%s\n' 'No se encontró curl.' >&2
fi
Ver información detallada con command -V
-V proporciona una explicación detallada que es más fácil de leer para las personas que -v.
command -V ls
command -V cd
command -V deploy
En la automatización, como el formato de la oración puede variar según la shell y la configuración regional, no se recomienda analizar la salida de -V. Para comprobar la existencia de un script, utilice el estado de finalización de command -v.
command -p y ruta de búsqueda predeterminada
-p utiliza el valor predeterminado de PATH proporcionado por la shell para encontrar utilidades estándar. Se puede usar cuando el PATH modificado por el usuario es poco confiable o se necesita encontrar un comando estándar.
command -p getconf PATH
command -p ls
El valor real de la ruta predeterminada varía según el sistema. -p no garantiza una ruta absoluta específica ni un programa de proveedor específico, por lo que en scripts donde la seguridad es importante, el entorno de ejecución y los límites de confianza deben diseñarse por separado.
Resumen de opciones de command
| Opciones | Descripción |
|---|---|
-v |
Muestra de manera concisa el resultado de la interpretación de la shell actual sin ejecutar el comando. |
-V |
Proporciona una explicación detallada de cómo se interpreta el comando. |
-p |
Ejecute un comando utilizando la ruta de búsqueda predeterminada donde se pueden encontrar utilidades estándar. |
Precauciones al eludir alias
La expansión de alias ocurre en una etapa de procesamiento de sintaxis del shell anterior a la ejecución del comando. En Bash interactivo, command ls generalmente se usa para ejecutar el comando real en lugar del alias ls, pero no debe considerarse como una herramienta de citación universal que controle tanto la definición del alias como el contexto de expansión del shell.
Todos los candidatos con el nombre actual se pueden verificar primero con type -a.
type -a ls
command -V ls
Si solo desea no aplicar el alias actual, también puede ingresar el nombre con una barra invertida o ejecutar la ruta absoluta verificada.
\ls
/usr/bin/ls
Una barra invertida evita la expansión de un alias, pero no omite una función del mismo nombre. Una ruta absoluta selecciona el archivo especificado, si existe y es ejecutable. Verifique esa ruta en su distribución antes de fijarla en un script.
Comparación de command, builtin, exec, env
| Comando | Rol principal |
|---|---|
command NOMBRE |
Omite la búsqueda de funciones del shell con el mismo nombre y ejecuta un comando integrado o PATH. |
builtin NOMBRE |
Ejecuta explícitamente un comando interno de Bash con el mismo nombre. |
exec NOMBRE |
Reemplaza el proceso de shell actual con un nuevo programa. Si tiene éxito, no volverá al shell original. |
env VAR=VALOR NOMBRE |
Ejecuta un comando externo en un entorno con variables de entorno ajustadas. |
type NOMBRE |
Muestra cómo Bash resuelve un nombre sin ejecutar el comando. |
Por ejemplo, dentro de una función, puede ser más claro usar builtin para asegurarse de llamar al comando interno de Bash con el mismo nombre, y usar command si también se permiten programas externos fuera de la función.
Principios al usar command -v en scripts
Descartar la salida y comprobar el estado de salida
if ! command -v rsync >/dev/null 2>&1; then
printf '%s\n' 'Se necesita rsync.' >&2
exit 1
fi
Este método no depende del formato de salida. Para ocultar incluso los mensajes de error, se deben redirigir tanto la salida estándar como el error estándar.
Si se necesita un archivo general ejecutable, realizar comprobaciones adicionales
Incluso si command -v tiene éxito, el resultado puede ser un alias, una función o un comando incorporado. Si realmente se necesita un archivo ejecutable externo, verifique adicionalmente si el resultado es una ruta y si es un archivo general ejecutable.
path=$(command -v mytool) || exit 1
if [ -f "$path" ] && [ -x "$path" ]; then
printf 'Archivo ejecutable: %s\n' "$path"
fi
El ejemplo supone que existe una herramienta llamada mytool. Comprueba que la cadena obtenida designa un archivo normal ejecutable, pero no demuestra por sí solo que el shell vaya a seleccionar ese archivo: por ejemplo, una función puede tener el mismo nombre que un archivo del directorio actual. Si necesita exigir un ejecutable externo, identifique una ruta con type -P en Bash, compruebe sus permisos y ejecute una ruta controlada.
Comprender el problema TOCTOU
TOCTOU significa Time Of Check To Time Of Use: el intervalo entre comprobar algo y utilizarlo. Después de command -v, la variable PATH o el archivo pueden cambiar antes de la ejecución. La comprobación ayuda a informar al usuario, pero en un entorno sensible también hacen falta rutas, permisos y límites de confianza controlados.
Estado de salida
En el modo de ejecución, un comando inexistente devuelve normalmente 127; si se encuentra pero no se puede ejecutar, puede devolver 126. Si se ejecuta, se propaga su estado: por ejemplo, false devuelve 1. Con -v y -V, el estado informa del resultado de la búsqueda y no ejecuta el comando encontrado.
command false
printf 'status=%d\n' "$?"
command does-not-exist
printf 'status=%d\n' "$?"
El estado de salida sigue el significado del comando ejecutado, por lo que un valor distinto de 0 no significa que command en sí esté roto.
Preguntas frecuentes
¿command solo ejecuta comandos externos?
No. En Bash, se omiten las funciones de shell y luego se ejecutan comandos incorporados o comandos externos encontrados en PATH. Para buscar solo archivos externos, debe verificar la ruta con una herramienta como type -P.
¿El resultado de command -v siempre es la ruta absoluta?
No. Puede devolver un alias, función, palabra reservada, comando incorporado o archivo ejecutable. Use el estado de salida para verificar la existencia de un comando.
¿Se puede usar en el formato sudo command ...?
command es un comando incorporado del shell, por lo que sudo puede que no pueda ejecutarlo directamente como un archivo independiente. Normalmente, pase el comando externo necesario directamente a sudo o, si realmente necesita la sintaxis del shell, ejecute explícitamente el shell entendiendo las citaciones y los efectos de seguridad.
¿Por qué command -v es mejor que which?
command -v es proporcionado por el shell y refleja la interpretación de comandos del shell actual. which suele ser un programa externo y, debido a diferencias de implementación, puede no manejar correctamente alias o funciones.
¿Cómo ejecutar solo comandos incorporados ignorando funciones?
En Bash se utiliza builtin NOMBRE. command NOMBRE puede ejecutar no solo comandos integrados, sino también comandos externos de PATH.
¿Se pueden usar las mismas opciones en otras shells?
El funcionamiento principal de -p, -v y -V está definido en POSIX, pero las frases de salida y las funciones ampliadas pueden variar según la shell. En automatización, defina la shell objetivo y consulte su documentación.
Al inspeccionar todos los candidatos y tipos de un comando, utilice type -a junto con ellos. Puede consultar otros comandos básicos en Lista y descripción general de comandos de Linux.
Compare los detalles de implementación en la Documentación oficial de comandos incorporados de GNU Bash, la Especificación de utilidad de comando POSIX y el Manual oficial de GNU Bash.




