From Nimish kamerkar
Answered By: Thomas Adam
Hi Answer Gang,
Which method is more efficient; Running a command in () or running it in a seperate shell? Can the answer include differences in how the processes are spawned? (i.e. fork exec etc)
[Thomas] OK. This is usually application/situation dependant. If you have something like:
#!/bin/bash echo $(whereis xterm)
What you are doing there is forcing the command "whereis xterm" to run in a subshell (denoted between ()'s). A "subshell" is just another instance of the command-line interpreter, running your program. Thus, a "subshell" in this instance means that the main shell script is its parent, i.e. assume that we called the script above "parent.sh" then when the subshell executed you'd get:
This is also known as forking -- i.e. where the process breaks off from the main caller, to form another.
"exec()"'ing a process however, means that the currently running process is replaced by the program that is to be exec'ed. Thus unlike above where-by the subshell ran under a new instance, the following script exec's itself:
See attached exec-anything.bash.txt
What this is doing is it will echo the first two lines, sleep for a second and then re-spawn itself. What you'll see is the same message above. The echo line will NEVER show, because it is after the program ($0 denotes the program's name) that is being (re)exec'ed.
My question is how are invoking a program in a subshell() and invoking it in a seperate shell different, as regards fork & exec. I am asking this as the environment inherited by both is different. I started thinking of this really because I remembered reading somewhere sometime that invoking it in () is more efficient than in a seperate shell. But as far as I can see, both processes should need fork and exec.
Only difference is in (), both the local and global environment variables are initialised, and in a seperate shell, only global environment variables are initialised. By that logic actually, the seperate process should be more efficient than the one in ()!
[Thomas] Those variables that are exported are "global" anyway, so you don't need to describe them in this way.
It depends. A subshell can be efficient if you want to ensure that a task running under another shell script is carried out to completion before the next one is executed (a good example of this would be tarring files over ssh on a pipe).
Of course, invoking a subshell program means that if the parent dies or is kill -9'ed, whatever, then the child process is also killed along with it. That is something you might want to consider.
Normally, when you write a shell script, and you want to end the script by calling another one then you would "exec" the program name, since there is no need for the shell process to fork().
If you need two independant processes to communicate concurrently then using a fork() would be best.
Hello Thomas/Answer Gang,
Thanks for the patient unravelling of the intricacies!
With Warm Regards -Nimish.
|Meet the Gang 1 2 3 4 5 6 7 8|