Determining if a process is running with pgrep

I have a script that I want to use only once. If the script call is called a second time, I check if the lock file exists. If the lock file exists, I want to check if the process is really running.

I worked with pgrep, but I do not get the expected results:

#!/bin/bash COUNT=$(pgrep $(basename $0) | wc -l) PSTREE=$(pgrep $(basename $0) ; pstree -p $$) echo "###" echo $COUNT echo $PSTREE echo "###" echo "$(basename $0) :" `pgrep -d, $(basename $0)` echo sleeping..... sleep 10 

The results I get are as follows:

 $ ./test.sh ### 2 2581 2587 test.sh(2581)---test.sh(2587)---pstree(2591) ### test.sh : 2581 sleeping..... 

I do not understand why I get "2" when only one process is running.

Any ideas? I am sure this is what I call it. I tried several different combinations and cannot figure out how to figure it out.

DECISION:

What I ended up doing this (part of my script):

 function check_lockfile { # Check for previous lockfiles if [ -e $LOCKFILE ] then echo "Lockfile $LOCKFILE already exists. Checking to see if process is actually running...." >> $LOGFILE 2>&1 # is it running? if [ $(ps -elf | grep $(cat $LOCKFILE) | grep $(basename $0) | wc -l) -gt 0 ] then abort "ERROR! - Process is already running at PID: $(cat $LOCKFILE). Exitting..." else echo "Process is not running. Removing $LOCKFILE" >> $LOGFILE 2>&1 rm -f $LOCKFILE fi else echo "Lockfile $LOCKFILE does not exist." >> $LOGFILE 2>&1 fi } function create_lockfile { # Check for previous lockfile check_lockfile #Create lockfile with the contents of the PID echo "Creating lockfile with PID:" $$ >> $LOGFILE 2>&1 echo -n $$ > $LOCKFILE echo "" >> $LOGFILE 2>&1 } # Acquire lock file create_lockfile >> $LOGFILE 2>&1 \ || echo "ERROR! - Failed to acquire lock!" 
+4
source share
3 answers

The argument to pgrep is an extended regular expression pattern. In this case, the pgrep $(basename $0) command will evaluate to pgrep test.sh , which will match any process that has test , followed by any character, and finally followed by sh . So this corresponds to btest8sh , atest_shell , etc.

You should create a lock file. If the lock file exists, the program should exit.

 lock=$(basename $0).lock if [ -e $lock ] then echo Process is already running with PID=`cat $lock` exit else echo $$ > $lock fi 
+3
source

You are already opening a lock file. Use it to make your life easier.

Write the process ID to the lock file. When you see a lock file, read it to find out what process identifier it supposedly blocks, and check if this process is running.

Then in version 2 you can also write down the program name, program arguments, program start time, etc., to protect against the case when a new process starts with the same process identifier.

0
source

Put this at the top of your script ...

 pid=$$ script=$(basename $0) guard="/tmp/$script-$(id -nu).pid" if test -f $guard ; then echo >&2 "ERROR: Script already runs... own PID=$pid" ps auxw | grep $script | grep -v grep >&2 exit 1 fi trap "rm -f $guard" EXIT echo $pid >$guard 

And yes, there is a small window for the race condition between the test and echo commands, which can be fixed by adding protection to the file, and then checking that the first line is really our own PID. In addition, the diagnostic output in if can be commented on in the production version.

0
source

Source: https://habr.com/ru/post/1394302/


All Articles