I am having a trivial doubt. Please see the below pipeline code sequence.
command1 | (command 2; commend 3)
I am aware that the command that follows pipe will run in the sub shell by the Unix kernel. But how about here? Since these set of commands are grouped under "parantheses", will they run inside another sub shell of pipe's shell? Hope my question is not so be-wilder to be answered
We're not ignoring you if we haven't answered the instant you want an answer. You don't have to bump threads. In fact you shouldn't, it's against the rules you read and agreed to when you registered.
I don't think you've got that quite right. Without complex structures like brackets or loops, a command after a pipe needs no subshell. The shell just creates a new process, arranges the files how you wanted, and replaces the new process with the requested command.
A subshell does have to stick around to manage situations like you illustrated:
command1 | ( command2 ; command3 )
It has to stay resident in order to wait for command2 to finish before starting command3.
A subshell also exists in a situation like this:
command1 | while read LINE
do
echo "${LINE}"
done
The subshell has to stay resident to process code after the pipe inside the loop.
But, anything to the right of a pipe will run in a subshell, not just loops. In non POSIX shells, the pipe spawns the sub shell. The use of a single pipe in a shell creates TWO subshells, one for each side (a pipeline with two | creates three subshells, for the three commands, etc.)
So my question is, how many subshells would've spawned in this scenario.
Also, in
(command &)
The background job detaches from the current shell and runs in a subshell (separate environment) and also, we are encapsulating this command inside parantheses, hence we are forcing it to run inside a subshell again. So would it create 2 subshells here? one for parantheses and one for "background"??
I think you're under a misapprehension here. The shell does clone itself in order to do redirection through pipes, but unless its actually needed, the subshell does not stick around: Once it's redirected file descriptors the way you asked it to, it replaces itself with the program you asked it to run. By the very act of running the process you asked it to, the subshell is wiped out. In its place is a brand new process with all the same redirections as the subshell used to have.
Not "also". A subshell remains because you encapsulated it with brackets. If you had not, no subshell would remain -- the subshell would exist for less than eyeblink, connecting file descriptors as specified then replacing itself with the new command. Why bother waiting around when there's nothing left for it to do?
...I'm beginning to have a sneaking suspicion that when you say "subshell" you mean "process". Not all processes are shells.
When you ask the shell to run the "cat" command the shell calls one of the exec functions:
The result is the cat executable is then running in the new process, not the shell.
When the process ends, the shell resumes in the parent process which waited for the cat process to end.