On 19 July 2017 00:38:06 BST, Robert Elz <k...@munnari.oz.au> wrote:
>Personally I think "env" should be restricted in usage to "run a
>utility after
>manipulating the environment" and not have any other semantics applied
>to it.

In effect, env is the cli to the execve system call.

>
>  | exec is the in-same-process command, it is not known as a
>  | bypass-builtin-and-function-lookup one
>
>I am similarly not sure of that either - it may be true - or might
>not, certainly I see no reason to prefer env over exec for this.
>Neither of them seems to really be specific to this purpose.

I agree, none of them is specific to the purpose and it's unfortunate that exec 
is called exec while in effect it's a in-same-process command (especially for 
the exec > redir) case, but I see several reasons to prefer env over exec:

1 it's more portable

2 env is the well known canonical way to do it

3 env is typically not used in a Bourne like shell for passing env vars. There, 
env var=value cmd is better written as var=value cmd. The main usages in sh is 
for that specific purpose (bypass builtins), or env -i or env %weird%var=value 
cmd. It is typically an external command called by other things like other 
shells. In any case, there's no reason to use it for builtins (at least not the 
commands that are typically implemented as builtins). On the other hand, exec 
is a special builtin which is never an external utility, it is always used in 
shells only and to make sure the command invoked is the last in the script (or 
subshell) and running with the same pid. It's unintuitive that it would be 
invoking a different command than without exec (especially in the case of 
commands wrapped by functions).


>
>I would say on behalf of picking "exec" though, that once upon a time,
>there was a general practice of having a command (the English word, not
>the shell grammar term) for every system call that could possibly be
>implemented in a standalone command.

I agree but in the case of exec, it's already broken in that exec >&2 doesn't 
execute anything.


>
>  | That should be
>  |   exec "$@"
>
>I considered that when I put it there, but decided to to omit it,
>precisely
>because of this ambiguity over just where exec (and env) look for the
>utility named.
>
>I also see no requirement anywhere that env directly exec its utility
>arg, rather that using a fork with a wait in the parent, and an exec
>in the child.

I don't agree. In practice you know that you can do

env var=value cmd &
...
kill "$!"

And that kill will not kill only the env command and leave cmd running 
unattended (in practice, there's no such guarantee with sh -c cmd which is one 
typical case where you need to use exec).


>
>All this is why I suggested that perhaps the "command" utility might
>be the right place to put the decision on where to look, leave env
>to environment manipulations, and exec to shell replacement (both
>finding
>the utility wherever they can) and have "command" (which is already
>specified as not invoking functions) be able to also not invoke
>builtins.

So you mean a pdksh-like exec and a command -e to bypass builtins? And exec 
command -e cmd to run an external cmd in the same process?

That would work for me, but that would break existing shell implementations, 
and unless anybody knows of a counterexample, env cmd is an existing, portable 
(contrary to exec) way to bypass builtins.

I see no strong reason to force mksh, zsh to break their backward compatibility 
(especially considering that the ability to do exec myfunction is a feature 
there, extra code is needed to implement it. It is by design and not an 
accident of implementation like in the case of ksh).

If we leave it unspecified whether exec works with functions or builtins, users 
can still do:

cmd; exit

To make sure the builtin cmd (or function) is run as the last command, or

exec env cmd

To execute the external cmd in the same process.

And no shell needs to be modified.
-- 
Stéphane

Reply via email to