I need some help because I don't get something. From what I read from Internet, a subshell is created when we execute a shell script or if we run command in brackets: ( )
I tried to test this with a script which contains only the following command:
ps -f
When I run it I see the following result:
ID PID PPID C STIME TTY TIME CMD
me 2213 2160 0 08:53 pts/14 00:00:00 bash
me 3832 2213 0 18:41 pts/14 00:00:00 bash
me 3833 3832 0 18:41 pts/14 00:00:00 ps -f
Which is good, because I see that my bash process has spawned another bash process for my script.
But when I do:
( ps -f )
it produces:
UID PID PPID C STIME TTY TIME CMD
me 2213 2160 0 08:53 pts/14 00:00:00 bash
me 3840 2213 0 18:46 pts/14 00:00:00 ps -f
So if brackets spawn a subshell why it is not shown in the processes? And why does ps -f
is counted as another process? Does every command run as a separate process?
It seems you've caught bash
in a little bit of an optimization. if a subshell contains only a single command, why really make it a subshell?
$ ( ps -f )
UID PID PPID C STIME TTY TIME CMD
jovalko 29393 24133 0 12:05 pts/10 00:00:00 bash
jovalko 29555 29393 0 12:07 pts/10 00:00:00 ps -f
However, add a second command, say :
(the bash null command, which does nothing) and this is the result:
$ ( ps -f ; : )
UID PID PPID C STIME TTY TIME CMD
jovalko 29393 24133 0 12:05 pts/10 00:00:00 bash
jovalko 29565 29393 0 12:08 pts/10 00:00:00 bash
jovalko 29566 29565 0 12:08 pts/10 00:00:00 ps -f
One of the main reasons to use a subshell is that you can perform operations like I/O redirection on a group of commands instead a single command, but if your subshell contains only a single command there's not much reason to really fork a new bash process first.
As to ps
counting as a process, it varies. Many commands you use like ls
, grep
, awk
are all external programs. But, there are builtins like cd
, kill
, too.
You can determine which a command is in bash
using the type
command:
$ type ps
ps is hashed (/bin/ps)
$ type cd
cd is a shell builtin
The main part of the question is:
Does every command run as a separate process?
YES!. Every command what isn't built-in into bash (like declare
and such), runs as separate process. How it is works?
When you type ps
and press enter, the bash analyze what you typed, do usual things as globbing, variable expansionas and such, and finally when it is an external command
forks
itself.The forking mean, than immediatelly after the fork, you will have two identical bash
processes (each one with different process ID (PID)) - called as "parent" and "child", and the only difference between those two running bash
programs is, than the "parent" gets (return value from the fork
) the PID of the child but the child don't know the PID of the parent. (fork for the child returns 0).
ps
) - using the exec
call. ps
.Of course, when the bash going to fork itself, do many other things, like I/O redirections, opens-closes filehandles, changes signal handling for the child and many-many other things.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With