Debian/Ubuntu supply Bash with an extension that lets you define a
function to be run whenever a command in an interactive shell hasn't
been found. As shipped it does things like this, which can be handy:
$ echo znetnerg gungpure | rot13
The program 'rot13' is currently not installed. You can install it by
typing: sudo apt-get install bsdgames
bash: rot13: command not found
This feature's documentation in its entirety, is an item in the 'Shell
Variables' list in bash(1):
command_not_found_handle
The name of a shell function to be called if a command cannot be
found. The return value of this function should be 0, if the
command is available after execution of the function, otherwise 127
(EX_NOTFOUND). Enabled only in interactive, non POSIX mode shells.
This is a Debian extension.
Points of hate:
* The docs suggest that you set $command_not_found_handle to the name of
the function you want to run. I couldn't get this to work.
The shipped function is called command_not_found_handle (and
$command_not_found_handle doesn't appear to be set anywhere); so far
as I can tell you simply define your function with that name for it to
work, and the documented variable simply doesn't exist.
* Because the API only provides for a single function, not an array of
them, it's needlessly hard to set up a series of fallbacks -- for
example to try the shipped 'uninstalled package' thing first and then
something else.
To get this your function has to duplicate the default behaviour
before adding in its own check. This obviously doesn't scale, and
makes assumptions about what the default behaviour is.
* The default function in its entirety is this:
command_not_found_handle ()
{
/usr/bin/python /usr/lib/command-not-found -- $1;
return $?
}
It only has two lines, and the second is entirely redundant! And the
underlying Python program that determines whether the command is a
program in an uninstalled package has the generic name
command-not-found rather than something which indicates what this
particular not-found handler does.
* Whether that program knows about the command (and successfully tells
you which package to install) or it can't help at all, the spec says
it has to return 127 (because in neither case has the command been
installed, for next time). This makes using it in a chain of
fallbacks more work than necessary, because you have to capture its
output to see if it's worked.
(Then save its exit code, check if there was any output, and if so
echo the output and exit with the exit code.)
How hard would it'd've been to come up with different exit codes to
distinguish these situations? Perhaps this 'uninstalled package'
scenario isn't one the authors of the feature considered -- except
that this is a Debian extension that appears to have been written
especially to provide this behaviour!
Grrr!
Smylers