7

I'm try to understand the classic service script /usr/sbin/service which has a line of code:

exec env -i ...... ${SERVICE} .....

I know the exec command doesn't fork, and will retain the process and replace the process image to the COMMAND. Then the current process is just like if executed with the COMMAND.

What about the env? Will it also do like the above?

And why is it better to replace the current process instead of forking?

muru
  • 72,889
lovespring
  • 2,061

1 Answers1

9

The reason it uses env -i is to clean out the environment variables before executing the rest of the command.

To really answer your question though, consider Windows:

In Windows, they give you "CreateProcess" which seems like a very sensible way to launch a new program. But the problem with CreateProcess is there are dozens of settings you might want to set for the new process, and for each setting you would need another parameter to the CreateProcess function call. This limits how much control the parent has over the child.

In Unix, they came up with the idea that one process first clones itself (inheriting all process settings) and then the second copy can change its settings before finally replacing itself with the new program. This lets you use any/all system calls to change things like current directory, environment, file handles, open sockets, signal masks, and so on without needing to add each one of these as a parameter to something like CreateProcess.

Then, a neat ability is to "chain" programs that perform different startup actions. Each program changes something about itself, then "exec"s into the next program. env is one of these programs. It modifies its own environment, then execs another program. See chpst for a great example of all the things you can change in the program you want to start.

dataless
  • 1,719
  • so, the env will not fork a process, it will run the command in the current process just like the "exec" does ? – lovespring Feb 24 '16 at 10:40
  • Yes, and you can check this by running env -i sleep 50 in one terminal, and then run ps fx in another terminal and you will see that "sleep" is a child process of "bash" and "env" is not there. – dataless Mar 07 '16 at 22:21
  • @dataless Why not exec -c instead of env -i? Doesn't exec -c clean out the environment too? The real benefit seems to not be the clearing of the environment but the ability to pass on some option (for example a PATH) to the new clean environment. – Pro Backup Dec 02 '16 at 14:28
  • Because env -i was what the original question asked about and setting variables wasn't mentioned, and my reply was about the nature of chain-execing programs and why this is useful. Also exec -c might not be POSIX? (i.e. is specific to bash) – dataless Dec 07 '16 at 09:19