我有一个脚本可以杀死一个在linux上正常工作的进程树,但我在osx上遇到了一些奇怪的行为。它实际上适用于我的单元测试以及尝试在osx上手动运行时,但出于某种原因,当它作为jenkins工作运行时,它的行为方式不同。
所以这是当前的bash函数,带有一点调试回显和休眠:
killtree() {
local _pid=$1
local _sig=${2:--TERM}
echo "Stopping ${_pid}"
sleep 1
kill -stop ${_pid} # stop parent to avoid creation of new children
children=`pgrep -P ${_pid}`
echo "Children=$children"
sleep 1
for _child in $children; do
killtree ${_child} ${_sig}
done
echo "Killing child ${_pid}"
sleep 1
kill -${_sig} ${_pid}
}
调用pgrep,失败的运行可以pgrep -P 9651
打印出机器上的所有进程,并且当脚本试图杀死pid 0时脚本挂起。
但为什么会得到所有流程呢?当运行完成时,进程9651仍然在运行,如果我在命令行pgrep -P 9651
上发出命令,则根本没有输出(由于此进程应该没有子进程,所以预计会这样做。)
在这种情况下,尝试被杀死的进程是一个用于测试的简单sleep 10
。
我在列出子项之前添加了一个调试调用来打印进程树:
+ pstree='-+= 00001 root /sbin/launchd
\-+= 09774 root /usr/sbin/sshd -i
\-+- 09777 jenkins /usr/sbin/sshd -i
\-+= 09783 jenkins bash -c cd '\''/var/jenkins'\'' && java -jar slave.jar
\-+- 09784 jenkins /usr/bin/java -jar slave.jar
\-+- 09807 jenkins /Library/Java/JavaVirtualMachines/jdk1.7.0_21.jdk/Contents/Home/jre/bin/java -classpath/
\-+- 09817 jenkins /Library/Java/JavaVirtualMachines/jdk1.7.0_21.jdk/Contents/Home/jre/bin/java -
\--- 09828 jenkins sleep 10'
对我来说很正常,sleep 10
没有孩子。
任何想法 - 在尝试调试这几个小时后我有点卡住了?
(实际上我第一次在apple.stackexchange上发布,因为我只在osx上看到它,但是这可能是一个更好的地方,因为我的默认情况下我的pxp甚至不存在于osx中)
答案 0 :(得分:1)
一些搜索显示jenkins在修改后的环境PATH下运行任务(可能出于安全原因)。您需要确保:
或者,如果您在jenkins下修改PATH有困难,可以编辑脚本以包含完整的pgrep路径
首先确定你的pgrep在用户tty shell下的运行位置:
$ which pgrep
/opt/local/bin/pgrep
变化:
children=`pgrep -P ${_pid}`
要:
children=`/opt/local/bin/pgrep -P ${_pid}`
其他shell命令(echo,sleep,kill等)应该由命令shell本机解释,并且应该'不需要路径。