1
0
Fork 0
mirror of git://git.code.sf.net/p/zsh/code synced 2024-12-29 16:25:35 +01:00

39566: Improve usefulness of command_not_found_handler.

Don't behave as if command not found if return status is non-zero

as this may simply be the return status of the replacement command.
Let the function report a command not found instead.
This commit is contained in:
Peter Stephenson 2016-10-05 12:14:43 +01:00
parent 429f8ae71d
commit dc517212ca
4 changed files with 27 additions and 15 deletions

View file

@ -28,10 +28,11 @@ not handle this executable format in the kernel.
If no external command is found but a function tt(command_not_found_handler)
exists the shell executes this function with all
command line arguments. The function should return status zero if it
successfully handled the command, or non-zero status if it failed.
In the latter case the standard handling is applied: `command not
found' is printed to standard error and the shell exits with status 127.
Note that the handler is executed in a subshell forked to execute
an external command, hence changes to directories, shell parameters,
etc. have no effect on the main shell.
command line arguments. The return status of the function becomes the
status of the command. If the function wishes to mimic the
behaviour of the shell when the command is not found, it should
print the message `tt(command not found:) var(cmd)' to standard error
and return status 127. Note that the handler is executed in a
subshell forked to execute an external command, hence changes to
directories, shell parameters, etc. have no effect on the main shell.

9
README
View file

@ -101,6 +101,15 @@ For the more common case of non-repeatable options that take a single
argument, completion functions now have to unescape not only colons but
also backslashes when obtaining the option's argument from $opt_args.
6) Previously, if the function command_not_found_handler was run
in place of a command-not-found error, and the function returned
non-zero status, zsh set the status to 127 and printed an error message
anyway. Now, the status from the handler is retained and no additional
message is printed. The main reasons for this change are that it was not
possible to return a non-zero status to the parent shell from a command
executed as a replacement, and the new implementation is more consistent
with other shells.
Incompatibilities between 5.0.8 and 5.2
---------------------------------------

View file

@ -568,11 +568,14 @@ commandnotfound(char *arg0, LinkList args)
Shfunc shf = (Shfunc)
shfunctab->getnode(shfunctab, "command_not_found_handler");
if (!shf)
return 127;
if (!shf) {
lastval = 127;
return 1;
}
pushnode(args, arg0);
return doshfunc(shf, args, 1);
lastval = doshfunc(shf, args, 1);
return 0;
}
/*
@ -703,7 +706,7 @@ execute(LinkList args, int flags, int defpath)
if (!search_defpath(arg0, pbuf, PATH_MAX)) {
if (commandnotfound(arg0, args) == 0)
_exit(0);
_exit(lastval);
zerr("command not found: %s", arg0);
_exit(127);
}
@ -767,7 +770,7 @@ execute(LinkList args, int flags, int defpath)
if (eno)
zerr("%e: %s", eno, arg0);
else if (commandnotfound(arg0, args) == 0)
_exit(0);
_exit(lastval);
else
zerr("command not found: %s", arg0);
_exit((eno == EACCES || eno == ENOEXEC) ? 126 : 127);

View file

@ -120,14 +120,13 @@
print "Your command:" >&2
print "$1" >&2
print "has gone down the tubes. Sorry." >&2
return 1
return 42
}
ThisCommandDoesNotExistEither
127:Command not found handler, failure
42:Command not found handler, failure
?Your command:
?ThisCommandDoesNotExistEither
?has gone down the tubes. Sorry.
?(eval):7: command not found: ThisCommandDoesNotExistEither
local variable=outside
print "I am $variable"