What is the execution environment where `command [arguments]` in `exec command [arguments]` runs?

7,946

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.

Share:
7,946

Related videos on Youtube

Tim
Author by

Tim

Elitists are oppressive, anti-intellectual, ultra-conservative, and cancerous to the society, environment, and humanity. Please help make Stack Exchange a better place. Expose elite supremacy, elitist brutality, and moderation injustice to https://stackoverflow.com/contact (complicit community managers), in comments, to meta, outside Stack Exchange, and by legal actions. Push back and don't let them normalize their behaviors. Changes always happen from the bottom up. Thank you very much! Just a curious self learner. Almost always upvote replies. Thanks for enlightenment! Meanwhile, Corruption and abuses have been rampantly coming from elitists. Supportive comments have been removed and attacks are kept to control the direction of discourse. Outright vicious comments have been removed only to conceal atrocities. Systematic discrimination has been made into policies. Countless users have been harassed, persecuted, and suffocated. Q&A sites are for everyone to learn and grow, not for elitists to indulge abusive oppression, and cover up for each other. https://softwareengineering.stackexchange.com/posts/419086/revisions https://math.meta.stackexchange.com/q/32539/ (https://i.stack.imgur.com/4knYh.png) and https://math.meta.stackexchange.com/q/32548/ (https://i.stack.imgur.com/9gaZ2.png) https://meta.stackexchange.com/posts/353417/timeline (The moderators defended continuous harassment comments showing no reading and understanding of my post) https://cs.stackexchange.com/posts/125651/timeline (a PLT academic had trouble with the books I am reading and disparaged my self learning posts, and a moderator with long abusive history added more insults.) https://stackoverflow.com/posts/61679659/revisions (homework libels) Much more that have happened.

Updated on September 18, 2022

Comments

  • Tim
    Tim over 1 year

    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?

    • Nominal Animal
      Nominal Animal over 7 years
      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
      Nominal Animal over 7 years
      @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.
    • done
      done over 7 years
      The execution environment does not contain any non-environment variables, by definition. Therefore, preserving the execution environment could not preserve any non-environment variable.
    • Tim
      Tim over 7 years
      @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/…
    • done
      done over 7 years
      And those "shell parameters" (in shell parlance) are the only "environment variables" (in your words). There are no other variables. The other elements are not variables, are: open files, cwd, umask, traps, functions, options, aliases, pid's. Nothing of that is an "environment variable".
    • Tim
      Tim over 7 years
      @sorontar those "shell parameters" include those variables not exported to the environment.
    • done
      done over 7 years
      No, they don't. Variables not exported cease to exist in any other new shell (sub-shells are a very different issue).
  • Tim
    Tim over 7 years
    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?
  • Nominal Animal
    Nominal Animal over 7 years
    @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
    Nominal Animal over 7 years
    @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
    Nominal Animal over 7 years
    @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.
  • Tim
    Tim over 7 years
    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?
  • done
    done over 7 years
    @Tim Shell variables are lost when a new shell starts: a=42; echo "one=$a";bash -c 'echo "t22=$a"' will print one=42 t22= . the value of a shell variable $a is lost. In an exec, that is also true.
  • Tim
    Tim over 7 years
    @sorontar can you show that 'In an exec, that is also true.'
  • user9645
    user9645 over 3 years
    I'm confused by the backticks in your examples, e.g. bash -c [bt]exec env[bt] (where [bt] is a backtick, can't figure out how to format that in a comment). Shouldn't it be bash -c 'exec env' (which I tried and does what I expect)