2

I'm writing a script (show_volume.sh) which may be called several times in short intervals. I need a way to determine whether there is more than just one running instance of this script. I figured I could use ps, so I wrote this function in Bash:

is_only_process(){
    PCOUNT=`ps -a | grep show_volume.sh | wc -l`
    echo $PCOUNT
    if (( PCOUNT==1 )); then
        return 1 
    fi  
    return 0
}

So I added these 2 lines

is_only_process
sleep 4

and started this script once, but the output of echo $PCOUNT does not make any sense to me. I always get the value 2, not 1, as expected. When I run this command

ps -a | grep show_volume.sh | wc -l

from another terminal while the script is running, I receive the value 1. It's pretty much the same when I run this script several times in a row, e.g. 10 times using a for loop. The script itself determines values which are too high while I receive correct values when using another terminal.

Now, why does this script determine these odd values?

helios35
  • 1,577
  • 1
  • 14
  • 27

4 Answers4

6

At the moment ps runs a process grep show_volume.sh is also running, so you always count the grep!

Simple solution, grep s[h]ow_volume.sh. The grep (not shell) will collapse the [h] to h and search for what you want, but your grep won't match itself because it will have [] in the parameter.

pgrep is also useful for this task and is smart enough to always exclude itself.

Nathan Kidd
  • 2,919
  • 21
  • 22
  • "At the moment ps runs a process grep show_volume.sh is also running" - not technically correct. there are cases in which `ps` will finish before `grep` fires up, in which case the `grep` won't be counted. so you have to cater for both cases. – moinudin Dec 17 '10 at 18:41
  • For some reason, it doesn't solve my problem. I tried to replace the expression with `pgrep show_volume.sh | wc -l` or `ps -a | grep s[h]ow_volume.sh | wc -l`, but the script behaves exactly the same as before. – helios35 Dec 17 '10 at 18:58
  • @marcog, the reason I gave is the correct technical explanation for why he was getting 2 processes showing up in grep. You're right, however, that in general you have to be ware that you may *not* get that behaviour depending on your system's performance characteristics. – Nathan Kidd Dec 17 '10 at 19:37
  • @helios35, I suggest you examine the plain output of `ps -a | grep s[h]ow_volume.sh` and work from there. (Personally I'd use `ps -ef | ...` to ensure you catch the case where the script is passed as a parameter to a shell) – Nathan Kidd Dec 17 '10 at 19:39
  • `ps -ef | grep s[h]ow_volume.sh` helios 25929 1 0 15:22 ? 00:00:00 /bin/bash /home/helios/scripts/show_volume.sh helios 25961 25929 0 15:22 ? 00:00:00 /bin/bash /home/helios/scripts/show_volume.sh this is the output when I run the script once. I have no idea why there are 2 processes which don't really differ. – helios35 Dec 18 '10 at 14:23
  • 2nd instance was launched by the first (PIDs show it's a child). Check your script carefully for a recursive call. – Nathan Kidd Dec 22 '10 at 19:37
2

If you're running the script as different users then ps -a will only show instances for the current user and only those with an attached terminal. Use ps -ax or ps -e.

pgrep -c

will show a count without having to use wc.

Dennis Williamson
  • 346,391
  • 90
  • 374
  • 439
1

Try to exclude grep as well, as your grep itself also contains show_volume.sh, an example

ps -a | grep show_volume.sh | grep -v grep | wc -l
ajreal
  • 46,720
  • 11
  • 89
  • 119
0

The solution provided by ajreal:

ps -a | grep show_volume.sh | grep -v grep | wc -l

should work. If it does not, please provide output of

ps -a | grep show_volume.sh | grep -v grep

here

  • 1
    output: "ps -e | grep show_volume.sh | grep -v grep" 15956 ? 00:00:00 show_volume.sh 15971 ? 00:00:00 show_volume.sh two processes although I executed the script only once and excluded grep. – helios35 Mar 12 '11 at 10:05
  • `grep -v grep` is an antipattern. How to avoid it is an ancient FAQ. – tripleee May 11 '16 at 07:00