This is the behavior of pgrep
on my FreeBSD script:
luis@Balanceador:~/Temporal$ cat test.sh
#!/usr/bin/env bash
pgrep -fl "test.sh"
luis@Balanceador:~/Temporal$ ./test.sh
luis@Balanceador:~/Temporal$
No output. This is: the script itself is not detected as running. Just like the command-line behavior of pgrep
. This is fine for me.
And this is the Linux (Ubuntu) case:
luis@Terminus:~/Temporal$ cat test.sh
#!/usr/bin/env bash
pgrep -fl "test.sh"
luis@Terminus:~/Temporal$ ./test.sh
4514 bash
luis@Terminus:~/Temporal$
As can be seen, the test.sh
script itself seems to be detected as a running process.
I am developing a shell (Bash) script that must be able to stop and wait if another instance of it (same name) is detected, and must work on both Linux and FreeBSD, so I would like to homogeneize the pgrep command for this.
Is there any way to make both of them behave the same?
Answers for any derivative like grep
or ps
accepted.
Tested:
The -x
(exact) switch from the Man Page, but does not work with parameters on the scripts (or I don't understand how to make it work). Parameters are not important to detect (they could be whatever) in this case; I just need to detect the main '.sh' script.
Further Notes:
- Please, don't answer like "Use file locking". I actually want to know about the
pgrep
tool.
Best Answer
FreeBSD's
pgrep
excludes ancestors of thepgrep
process, including the script instance that ran it. Linux'spgrep
doesn't have a corresponding feature.You can exclude the script instance manually. The process id to exclude is in
$$
. You do need to be a bit careful to also avoid any subshell: the most straightforward methodpgrep … | grep -v "^$$ "
might list the right-hand side of the pipe ifpgrep
happens to reach it in the process list beforegrep
is invoked.