You are conflating two different things: execution environment and environment variables.
Environment variables are strings of form name=value
, and are used as a form of configuration for the commands and processes. For example, PATH
is a colon-separated list of directories where executable commands are looked for, when only the file name of the command is supplied; LANG
and various variables starting with LC_
control the locale, and so on.
Execution environment includes all the shell features that affect how commands might be run. It includes environment variables, of course, but also things like the working directory, file creation mask (umask
), shell functions and aliases defined, and so on.
At the point of execution -- the moment when the shell starts executing the command --, the execution environment is almost exactly the same in all cases, with or without exec
. With exec
, the shell EXIT
trap is triggered (because the shell is essentially exiting, when replaced by another process). With exec -c
, the environment variables are cleared.
The -c
flag to Bash exec
only clears the environment variables. If you run
bash -c `exec env`
you start a new Bash shell, which is then replaced by the env
command; which, when no other parameters are specified, just outputs all environment variables. However, if you add the -c
flag to exec
, i.e.
bash -c `exec -c env`
it prints nothing, and that is because env
is run with no environment variables (or, in other words, an empty environment).
(If you run just exec env
in a terminal, the shell running in the terminal will be replaced by the env
command, and when it exits, the terminal will close. It'll probably happen too fast for you to see. This is why I explicitly run it under Bash, as that way, it's that sub-Bash that gets replaced, and not the shell your terminal is using.)
I have not seen the -c
option used in real life scripts, as usually env -i
is used instead. For example:
bash -c `exec env -i PATH=$PATH env`
With parameters, the env
command is used to run a command with modified environment variables; the -i
option is used to start from scratch; i.e. clear all existing environment variables. Because the shell parses the entire command (line) before executing it, you can use env -i VAR=$VAR OTHER=$OTHER
to keep specific environment variables -- by telling env
to define them with the old values they had when the shell parsed the command line. In the above, the final env
just prints out the resulting environment variables, but it could be any other command.
-c
option to Bashexec
clears all environment variables -- try e.g.bash -c 'exec env'
andbash -c 'exec -c env'
. As to the execution environment, it is the same at the point of invocation of the command.