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?
Advertisement
Answer
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