tokosh tokosh - 5 months ago 13
Linux Question

Bash: Inline Execution returns Duplicate "Process". Why?

bash: 4.3.42(1)-release (x86_64-pc-linux-gnu)

Executing the following script:

# This is myscript.sh
line=$(ps aux | grep [m]yscript) # A => returns two duplicates processes (why?)
echo "'$line'"
ps aux | grep [m]yscript # B => returns only one


Output:

'tom 31836 0.0 0.0 17656 3132 pts/25 S+ 10:33 0:00 bash myscript.sh
tom 31837 0.0 0.0 17660 1736 pts/25 S+ 10:33 0:00 bash myscript.sh'
tom 31836 0.0 0.0 17660 3428 pts/25 S+ 10:33 0:00 bash myscript.sh


Why does the inline executed
ps
-snippet (A) return two lines?

Answer

Summary

This creates a subshell and hence two processes are running:

line=$(ps aux | grep [m]yscript) 

This does not create a subshell. So, myscript.sh has only one process running:

ps aux | grep [m]yscript       

Demonstration

Let's modify the script slightly so that the process and subprocess PIDs are saved in the variable line:

$ cat myscript.sh 
# This is myscript.sh
line=$(ps aux | grep [m]yscript; echo $$ $BASHPID)
echo "'$line'"
ps aux | grep [m]yscript  

In a bash script, $$ is the PID of the script and is unchanged in subshells. By contrast, when a subshell is entered, bash updates $BASHPID with the PID of the subshell.

Here is the output:

$ bash myscript.sh 
'john1024  30226  0.0  0.0  13280  2884 pts/22   S+   18:50   0:00 bash myscript.sh
john1024   30227  0.0  0.0  13284  1824 pts/22   S+   18:50   0:00 bash myscript.sh
30226 30227'
john1024   30226  0.0  0.0  13284  3196 pts/22   S+   18:50   0:00 bash myscript.sh

In this case, 30226 is the PID on the main script and 30227 is the PID of the subshell running ps aux | grep [m]yscript.