Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Bash - Two processes for one script

Tags:

bash

shell

unix

ps

I have a shell script, named test.sh :

#!/bin/bash
echo "start"
ps xc | grep test.sh | grep -v grep | wc -l
vartest=`ps xc | grep test.sh | grep -v grep | wc -l `
echo $vartest
echo "end"

The output result is :

start
1
2
end

So my question is, why are there two test.sh processes running when I call ps using `` (the same happens with $()) and not when I call ps directly? How can I get the desired result (1)?

like image 326
user6050469 Avatar asked Mar 08 '23 18:03

user6050469


1 Answers

When you start a subshell, as with the backticks, bash forks itself, then executes the command you wanted to run. You then also run a pipeline which causes all of those to be run in their own subshells, so you end up with the "extra" copy of the script that's waiting for the pipeline to finish so it can gather up the output and return that to the original script.

We'll do a little expermiment using (...) to run processes explicitly in subshells and using the pgrep command which does ps | grep "name" | grep -v grep for us, just showing us the processes that match our string:

echo "Start"
(pgrep test.sh)
(pgrep test.sh) | wc -l
(pgrep test.sh | wc -l)
echo "end"

which on a run for me produces the output:

Start
30885
1
2
end

So we can see that running pgrep test.sh in a subshell only finds the single instance of test.sh, even when that subshell is part of a pipeline itself. However, if the subshell contains a pipeline then we get the forked copy of the script waiting for the pipeline to finish

like image 169
Eric Renouf Avatar answered Mar 15 '23 09:03

Eric Renouf