1

I have a System V init script I've developed that starts a Java program. For some reason whenever the PID file gets created, it contains multiple PIDs instead of one.

Here's the relevant code that starts the service and writes to the PID file:

daemon --pidfile=$pidfile "$JAVA_CMD &" >> $logfile 2>&1
RETVAL=$?
usleep 500000

if [ $RETVAL -eq 0 ]; then
    touch "$lock"

    PID=$(ps aux | grep -vE 'grep|runuser|bash' | grep <myservice> | awk '{print $2}')

    echo $PID > $pidfile

When I test the ps aux... command manually, a single line returns. When running as a script, it appears that this call is returning multiple PIDs.

Example contents in the PID file: 16601 16602 16609 16619 16690. 16619 is the actual process ID found when manually running the ps aux... command mentioned above.

dmux
  • 442
  • 7
  • 24
  • 2
    I'd suggest that you remove the last awk command and check what's going on... – Jean-François Fabre Nov 01 '16 at 20:14
  • 2
    You are only interested in getting the `pid`. Instead of of using `ps` use `pgrep`. It returns just the `pid`. Try `PID=$(pgrep -f )`. Or take a shortcut. Don't assign to `$PID`. Try `pgrep -f > $pidfile`. – alvits Nov 02 '16 at 02:41

2 Answers2

2

Try reversing your greps. The first one (-vE) may run BEFORE the myservice one starts up. Grep for your service FIRST, then filter out the unwanted lines:

PID=$(ps aux | grep <myservice> | grep -vE 'grep|runuser|bash' | awk '{print $2}')
Marc B
  • 356,200
  • 43
  • 426
  • 500
0

I encounted the same issue but not the same statement, it was like this:

PID="$(ps -ef|grep command|grep options|grep -v grep|awk '{print $2}')"

in which I used the same grep order as @Marc said in first answer, but did not filter all the unwanted lines. So I tried the below one and it worked:

PID="$(ps -ef|grep command|grep options|grep -vE 'grep|runuser|bash'|awk '{print $2}')"
Togor
  • 306
  • 3
  • 6