viernes, 23 de abril de 2010

Manejando el Mensaje Bash "Comando no encontrado"

Algunas de las versiones mas recientes de las distribuciones más populares, como por ejemplo openSUSE 11.2, estan usando un bash un poco mas inteligente. Esta nueva versión de bash muestra mensajes de error más útiles cuando uno escribe un comando que no esta en el PATH pero si en un directorio "sbin".

Por ejemplo, si tipeas el comando ifconfig sin permisos de root te mostrara el siguiente mensaje:

$ ifconfig
Absolute path to 'ifconfig' is '/sbin/ifconfig',
so running it may require superuser privileges (eg. root).

Este mensaje esta diciendo que la ruta de ifconfig es '/sbin/ifconfig', y que por lo tanto necesitas permisos de administrador para ejecutarlo.

Lo cual de hecho es más util que el mensaje "Comando no encontrado" (Command not found).

Esto es una nueva función que se llama command_not_found_handle. Si se hace un grep en /etc se puede ver que es lo que sucede. La función se encuentra en /etc/bash_command_not_found y también viene incluida en la sesión bash vía /etc/bash.bashrc.

La función en si misma no es muy compleja, pero hay un par de cosas que seria interesante observar. El siguiente código determina si el shell invocado fue ejecutado desde el Midnight Commander o esta tomando entrada desde un pipe:

# do not run when inside Midnight Commander or within a Pipe
if test -n "$MC_SID" -o ! -t 1 ; then
echo $"$1: command not found"
return 127
fi

Y lo siguiente determina si el shell es invocado esta en un sub-shell:

# do not run when within a subshell
read pid cmd state ppid pgrp session tty_nr tpgid rest < /proc/self/stat
if test $$ -eq $tpgid ; then
echo "$1: command not found"
return 127
fi

Al final de la función hay una sentencia que usa /usr/bin/command-not-found (escrito en Python) para buscar comandos en paquetes instalables (via zypper) pero para eso necesitas configurar una variable de entorno (COMMAND_NOT_FOUND_AUTO) para activarla, y por supuesto tener Python instalado. Para probarlo has lo siguiente:

$ export COMMAND_NOT_FOUND_AUTO=1
$ pascal
pascal: command not found
$ gcj
The program 'gcj' can be found in the following package:
* gcc-java [ path: /usr/bin/gcj, repository: zypp (repo-oss) ]

Try installing with:
sudo zypper install gcc-java

Debido a que la funcionalidad command-not-found es manejada por una función bash, puedes reemplazar la función instalada en el sistema con una que tu hayas creado o modificado. Todo lo que necesitas hacer es incluirla en el archivo .bashrc.

Leído en LinuxJournal.

No hay comentarios: