Linux 如何使用Jenkins中的bash脚本从pid文件中读取来终止进程?

Linux 如何使用Jenkins中的bash脚本从pid文件中读取来终止进程?,linux,bash,jenkins,Linux,Bash,Jenkins,在詹金斯内部,我必须运行两个单独的脚本:start.sh和stop.sh。这些脚本位于从SCM获取的应用程序中。它们在同一个目录中 start.sh脚本使用nohup在后台运行一个进程,并将processId写入save_pid.pid。这个脚本很好用。它成功地启动了我的应用程序 然后在stop.sh中,我试图从save_pid.pid读取processId以删除进程。但是,我无法删除该进程,应用程序将一直运行,直到我使用以下命令手动终止该进程:sudo kill{processId} 以下是我

在詹金斯内部,我必须运行两个单独的脚本:start.shstop.sh。这些脚本位于从SCM获取的应用程序中。它们在同一个目录中

start.sh脚本使用nohup在后台运行一个进程,并将
processId
写入
save_pid.pid
。这个脚本很好用。它成功地启动了我的应用程序

然后在stop.sh中,我试图从
save_pid.pid
读取
processId
以删除进程。但是,我无法删除该进程,应用程序将一直运行,直到我使用以下命令手动终止该进程:
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


我认为发生这种情况的原因是,您没有得到感兴趣的进程的PID,而是执行命令的shell的PID

看:

所以“nohup”将执行“shell”,“shell”将分叉第二个“shell”来执行“sleep”,但是我在这里只能计算两个进程,所以我无法解释一个创建的PID

请注意,如果您将nohup和pgrep放在一行上,那么pgrep的启动速度显然会比“exec的”sleep“外壳更快,因此pgrep不会产生任何结果,这在一定程度上证实了我的理论:

$ nohup /tmp/foo & echo $! ; pgrep sleep
[2] 26899
nohup: ignoring input and appending output to 'nohup.out'
$
如果您直接启动流程,那么nohup将“执行”您的流程,从而使流程保持与nohup本身相同的PID(请参阅):

此外,如果在脚本中执行“sleep”,则只创建了一个进程(如预期的那样):


因此,根据我的理论,如果你在脚本中“执行”你的进程,那么你就会得到正确的PID。

你确定
/path/to/save\u PID.PID
的内容真的是你想要杀死的进程的PID吗?是的,我想是这样。由于stop.sh不工作,我手动读取
save_pid.pid
的内容,然后自己使用:
sudo kill{processId}
删除进程。之后,应用程序停止。所以,我猜这是正确的pid。你检查了脚本的错误输出了吗?如果
kill
由于某种原因失败,它应该会产生一条错误消息,提供一些线索。当我选中时,
save_pid.id
中的值:它总是比实际的
processId
小1,我的意思是总是。我是如何发现的,实际上,在start.sh中,
nohup
在端口9005中运行我的应用程序。当我列出所有打开的端口和相应的进程时,我看到一个对应于9005的
processId
,只比
save\u pid.id
的内容多1个。这怎么可能?我还检查了running stop.sh的输出。令人惊讶的是,除了我保存在那里的
echo
语句外,什么都没有。请注意,错误将打印到
stderr
,而不是
stdout
。如果您找不到打印
stderr
的位置,您可以暂时重定向它以进行调试,方法是写入
kill-9。。。2> &1
。至于为什么PID不同,似乎无论创建PID文件的是什么,它都没有正确执行。(没有编写正确的PID以终止进程)我尝试了:
nohup deploy\u script>$WORKSPACE/app.log 2>&1&echo$!>$工作区/save_pid.pid;pgrep sleep
,但它不起作用。事实上,创建的Id和实际Id的区别现在是2。从某种意义上说,即使在我的nohup脚本中添加了
pgrep sleep
,正如我在前面的评论中所示,我仍然无法在
save_pid中获得准确的
processId
。pid
pgrep sleep
无法帮助您获得进程的pid。PID被关闭了2,因为您得到的PID显然是正在执行脚本的shell的PID,而不是正在启动的进程的PID。要获取正在启动的进程的PID,需要输出
echo$在脚本中。好的。我的问题是,我无法修改
deploy\u脚本
。每次运行应用程序时,它都由应用程序的构建系统自动生成。在这种情况下,你建议我做什么?我仍然需要在后台运行脚本。
nohup deploy_script>$WORKSPACE/app.log 2>&1&echo$($!-1))>$WORKSPACE/save_pid.pid
,但这确实是一个丑陋的黑客行为!
$ nohup /tmp/foo & echo $! ; pgrep sleep
[2] 26899
nohup: ignoring input and appending output to 'nohup.out'
$
$ nohup /bin/sleep 10 & echo "$!"; pgrep sleep
[1] 27130
27130
nohup: ignoring input and appending output to 'nohup.out'
27130
$ 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