Skip to content
Advertisement

Why does (ps -f) create no subshell but a separate process?

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
User contributions licensed under: CC BY-SA
1 People found this is helpful
Advertisement