From bash manual

exec

exec [-cl] [-a name] [command [arguments]]

If command is supplied, it replaces the shell without creating a new process. If the -l option is supplied, the shell places a dash at the beginning of the zeroth argument passed to command. This is what the login program does. The -c option causes command to be executed with an empty environment.

Without -c option, what is the execution environment where command [arguments] runs?

  • Is it the same as the execution environment in the original shell process before running exec command [arguments]?

  • The execution environment in the original shell process contains not only environment variables but also all the shell variables including non-environment ones. Does the execution environment where command in exec command runs also include the non-environment variables in the original shell process?

Can you give some examples to show that?

  • 1
    You're conflating two things: execution environment and environment variables. The -c option to Bash exec clears all environment variables -- try e.g. bash -c 'exec env' and bash -c 'exec -c env'. As to the execution environment, it is the same at the point of invocation of the command. – Nominal Animal Dec 10 '16 at 15:28
  • @NominalAnimal, you should make that an answer. – glenn jackman Dec 10 '16 at 15:29
  • @glennjackman: Done, but since I seem to be physically unable to avoid being verbose (I'm not kidding, and I don't mean that as a joke!), it grew into a wall of text. If you care, you (or somebody else) could write a more concise summary, since I believe very few will bother to read my long-winded answer. – Nominal Animal Dec 10 '16 at 15:53
  • The execution environment does not contain any non-environment variables, by definition. Therefore, preserving the execution environment could not preserve any non-environment variable. – sorontar Dec 10 '16 at 20:19
  • @sorontar The execution environment does contain any non-environment variables. "The shell has an execution environment, which consists of the following: ... shell parameters that are set by variable assignment or with set or inherited from the shell’s parent in the environment" gnu.org/software/bash/manual/html_node/… – Tim Dec 10 '16 at 20:28
up vote 2 down vote accepted

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.

  • Thanks. In the execution environment where command in exec command runs, are the aspects other than environment variables the same as those in the execution environment in the original shell process? – Tim Dec 10 '16 at 16:05
  • @Tim: At the point of execution, everything. (Well, unless you consider it a difference that with exec, the EXIT trap is triggered before the command is run.) – Nominal Animal Dec 10 '16 at 16:09
  • @Tim: exec really is that simple. See, for example, the exec POSIX documentation. It is very often used when the shell script is used to modify environment variables, maybe check parameters or environment variables, and then replace itself with the proper application. In many Linux distributions, many applications -- even Firefox -- use such scripts to launch the application proper. It makes it simpler to use the same application in different distributions, as only small changes are needed in the script part. – Nominal Animal Dec 10 '16 at 16:18
  • @Tim: If you do not use exec in those cases, the shell will remain in memory, doing nothing, for as long as the application runs. (While it does not waste much CPU, it does waste resources, a bit of memory at least.) As soon as the application exits, the script will exit too. So, there really is no need for having the shell remain in memory; exec is the way to avoid that. – Nominal Animal Dec 10 '16 at 16:20
  • the execution environment in the original shell process contains not only environment variables but also all the shell variables including non-environment ones. Does the execution environment where command in exec command runs also include the non-environment variables in the original shell process? – Tim Dec 10 '16 at 17:58

Your Answer

 

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.