--- doc/bash.1 +++ doc/bash.1 @@ -2035,6 +2035,13 @@ be a prefix of a stopped job's name; this provides functionality analogous to the \fB%\fP\fIstring\fP job identifier. .TP +.B 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. +.TP .B histchars The two or three characters which control history expansion and tokenization (see --- doc/bashref.texi +++ doc/bashref.texi @@ -4809,6 +4809,13 @@ @item UID The numeric real user id of the current user. This variable is readonly. +@item 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. + @end vtable @node Bash Features --- execute_cmd.c +++ execute_cmd.c @@ -3722,8 +3722,26 @@ if (command == 0) { - internal_error (_("%s: command not found"), pathname); - exit (EX_NOTFOUND); /* Posix.2 says the exit status is 127 */ + SHELL_VAR *f, *v; + WORD_LIST *cmdlist; + WORD_DESC *w; + int fval; + if( (posixly_correct || interactive_shell == 0) || + (f = find_function ("command_not_found_handle")) == 0) + { + internal_error (_("%s: command not found"), pathname); + exit (EX_NOTFOUND); /* Posix.2 says the exit status is 127 */ + } + w = make_word("command_not_found_handle"); + cmdlist = make_word_list(w, (WORD_LIST*)NULL); + + w = make_word(pathname); + cmdlist->next = make_word_list(w, (WORD_LIST*)NULL); + + fval = execute_shell_function (f, cmdlist); + if (fval == EX_NOTFOUND) + internal_error (_("%s: command not found"), pathname); + exit(fval); } /* Execve expects the command name to be in args[0]. So we