Enganche al controlador "comando no encontrado" en Ubuntu

9

Quiero conectarme al controlador para el comando no encontrado

wim@SDFA100461C:~$ thing
No command 'thing' found, did you mean:
 Command 'tping' from package 'lam-runtime' (universe)
 Command 'thin' from package 'thin' (universe)
thing: command not found

Quiero anular este comportamiento con mi propio script.

Específicamente, quiero verificar si el comando existe en la salida de lsvirtualenv -b, y si es así, quiero activar ese virtualenv.

¿Dónde debería comenzar a hackear?

wim
fuente
1
Esto podría ayudar: askubuntu.com/a/73282/10127
glenn jackman

Respuestas:

8

En general

El Linux Journal tiene un artículo bastante bueno:

De la página de manual de bash:

... Se realiza una búsqueda completa de los directorios en PATH solo si el comando no se encuentra en la tabla hash. Si la búsqueda no tiene éxito, el shell busca una función de shell definida llamada command_not_found_handle. Si esa función existe, se invoca con el comando original y los argumentos del comando original como argumentos, y el estado de salida de la función se convierte en el estado de salida del shell. Si esa función no está definida, el shell imprime un mensaje de error y devuelve un estado de salida de 127.

y

Un rápido grep en / etc descubrió dónde estaba sucediendo. La función en sí está en / etc / bash_command_not_found y esa función se incluye (si existe) en su sesión de bash a través de /etc/bash.bashrc.

Ubuntu 14.04

La evidencia empírica sugiere que en una instalación de Ubuntu 14.04, el archivo / etc / bash_command_not_found no existe, sin embargo, el archivo correcto es un script de Python, ubicado en / usr / lib / command-not-found

Andrew Stubbs
fuente
1
Esto me puso en el camino correcto, pero el programa real era un script de Python ubicado en /usr/lib/command-not-found. En mi instalación de Ubuntu 14.04, el archivo /etc/bash_command_not_foundno existe.
wim
Gracias, lo he agregado a mi respuesta para futuros espectadores
Andrew Stubbs,
1

Para bash, su comportamiento se rige por la función de shell command_not_found_handle(Ver man bash, bajo la EJECUCIÓN DE MANDO).

Para ver qué comportamiento define esa función, puede emitir:

declare -p -f command_not_found_handle

Puede cambiar qué programa se utiliza redefiniendo la command_not_found_handlefunción.

En Ubuntu 14.04 LTS, parece que el comportamiento predeterminado se define directamente en /etc/bash.bashrc:

# if the command-not-found package is installed, use it
if [ -x /usr/lib/command-not-found -o -x /usr/share/command-not-found/command-not-found ]; then
    function command_not_found_handle {
            # check because c-n-f could've been removed in the meantime
            if [ -x /usr/lib/command-not-found ]; then
               /usr/lib/command-not-found -- "$1"
               return $?
            elif [ -x /usr/share/command-not-found/command-not-found ]; then
               /usr/share/command-not-found/command-not-found -- "$1"
               return $?
            else
               printf "%s: command not found\n" "$1" >&2
               return 127
            fi
    }
fi
Randall
fuente