How to kill a process by reading from pid file using bash script in Jenkins?

Viewed 3433

Inside Jenkins, I have to run 2 separate scripts: start.sh and stop.sh. These scripts are inside my application which is fetched from a SCM . They are inside same directory.

The start.sh script runs a process in the background using nohup, and writes the processId to save_pid.pid. This script works fine. It successfully starts my application.

Then inside stop.sh, I am trying to read the processId from save_pid.pid to delete the process. But,I am unable to delete the process and the application keeps running until I kill the process manually using: sudo kill {processId}.

Here are the approaches that I have tried so far inside stop.sh but none of these work:

kill $(cat /path/to/save_pid.pid)

kill `cat /path/to/save_pid.pid`

kill -9 $(cat /path/to/save_pid.pid)

kill -9 `cat /path/to/save_pid.pid`

pkill -F /path/to/save_pid.pid

I have also tried all of these steps with sudo as well. But, it just doesn't work. I have kept an echo statement inside stop.sh, which prints and then there is nothing.

What am I doing wrong here ?

UPDATE:

The nohup command that I am using inside start.sh is something like this:

nohup deploy_script > $WORKSPACE/app.log 2>&1 & echo $! > $WORKSPACE/save_pid.pid

Please Note:

In my case, the value written inside save_pid.pid is surprisingly always less by 1 than the value of actual processId. !!!

1 Answers

I think the reason why this happens is because you are not getting the PID of the process that you are interested in, but the PID of the shell executing your command.

Look:

$ echo "/bin/sleep 10" > /tmp/foo
$ chmod +x /tmp/foo
$ nohup /tmp/foo & echo $!
[1] 26787
26787
nohup: ignoring input and appending output to 'nohup.out'
$ pgrep sleep
26789

So 'nohup' will exec the 'shell', the 'shell' will fork a second 'shell' to exec 'sleep' in, however I can only count two processes here, so I am unable to account for one created PID.

Note that, if you put the nohup and the pgrep on one line, then pgrep will apparently be started faster than the shell that 'exec's 'sleep' and thus pgrep will yield nothing, which somewhat confirms my theory:

$ nohup /tmp/foo & echo $! ; pgrep sleep
[2] 26899
nohup: ignoring input and appending output to 'nohup.out'
$

If you launch your process directly, then nohup will "exec" your process and thus keep the same PID for the process as nohup itself had (see http://sources.debian.net/src/coreutils/8.23-4/src/nohup.c/#L225):

$ nohup /bin/sleep 10 & echo "$!"; pgrep sleep
[1] 27130
27130
nohup: ignoring input and appending output to 'nohup.out'
27130

Also, if you 'exec' 'sleep' inside the script, then there's only one process that's created (as expected):

$ echo "exec /bin/sleep 10" > /tmp/foo
$ nohup /tmp/foo & echo "$!"; pgrep sleep
[1] 27309
27309
nohup: ignoring input and appending output to 'nohup.out'
27309

Thus, according to my theory, if you'd 'exec' your process inside the script, then you'd be getting the correct PID.

Related