在 Jenkins 中,我必须运行2个单独的脚本: start.sh 和 stop.sh 。这些脚本位于我的应用程序中,该应用程序是从SCM获取的。它们位于同一目录中。
start.sh 脚本使用 nohup 在后台运行流程,并将processId
写入save_pid.pid
。这个脚本工作正常。它成功启动了我的申请。
然后在 stop.sh 内,我尝试从processId
读取save_pid.pid
以删除该过程。但是,我无法删除该进程,并且应用程序一直运行,直到我使用:sudo kill {processId}
手动终止该进程。
以下是我在 stop.sh 中尝试过的方法,但这些方法都不起作用:
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
我也使用sudo
尝试了所有这些步骤。但是,它只是不起作用。我在 stop.sh 中保留了一个echo
声明,该声明打印出来然后什么都没有。
我在这里做错了什么?
更新:
我在 start.sh 中使用的nohup
命令是这样的:
nohup deploy_script > $WORKSPACE/app.log 2>&1 & echo $! > $WORKSPACE/save_pid.pid
请注意:
就我而言,
save_pid.pid
内写的值令人惊讶 总是比实际processId
的值少1。 !!!
答案 0 :(得分:1)
我认为发生这种情况的原因是因为您不获取您感兴趣的进程的PID,但执行命令的 shell 的PID
查找
$ 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
所以' nohup'将执行' shell' shell'将分叉第二个贝壳'执行“睡觉” in,但是我只能计算两个进程,所以我无法计算一个创建的PID。
请注意,如果你将nohup和pgrep放在一行上,那么pgrep显然会比那些执行“睡眠”的shell更快地启动。因此pgrep什么都不会产生,这在某种程度上证实了我的理论:
$ nohup /tmp/foo & echo $! ; pgrep sleep
[2] 26899
nohup: ignoring input and appending output to 'nohup.out'
$
如果你直接启动你的流程,那么nohup会" exec"你的过程,因此保持与nohup本身相同的PID(参见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
另外,如果你' exec' '睡眠'在脚本中,然后只创建了一个进程(如预期的那样):
$ 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
因此,根据我的理论,如果你是“执行”的话。您在脚本中的过程,然后您将获得正确的PID。