gpt4 book ai didi

java - 杀死 screen 但java进程没有结束

转载 作者:行者123 更新时间:2023-11-30 09:01:19 38 4
gpt4 key购买 nike

我正在运行一个基本上运行一堆服务器以进行本地测试的脚本。

这些 jar 在不同的 screen 中运行,因为它们需要独立地接受键盘输入。为此,我使用了 screen 。

command1="java -jar $fullPath"
screen -d -m -S "${screenName[$i]}" bash -c "$command1"

效果很好!

然后我需要一种杀死所有服务器的方法

所以我写了一个脚本来做到这一点

for session in $(screen -ls | grep -o "[0-9]*\.${screenName[$i]}")
do
screen -X -S "$session" quit
echo "killing screen $session"
done

screen 被杀死时效果很好。但是第二次我做那个 java 突然占用了我 100% 的 CPU。

在我使用退出 screen 命令之前

The servers running normally

在我使用退出 screen 命令之后

enter image description here

他们还需要很长时间才能使用强制退出通过 gui 杀死

enter image description here

其他信息:

  • 服务器使用在一个 java 线程上运行的 Jetty。然后另一个线程只是等待键盘输入。
  • 显然这是在 mac 上运行,脚本在 bash 中,所以我想要一个适用于 mac 和 linux 的 bash 解决方案。
  • 它们也是使用 java 7 构建的,但使用 java 8 运行

因为服务器正在接受键盘输入,所以发送到 screen 的所有命令都由服务器接收。他们确实有退出他们的输入,但我不想相信服务器会退出。

所以我的问题是:

  • 有没有办法让 screen 在终止时终止其中所有正在运行的进程?

  • 如果没有,有没有办法将 ctrl-c 发送到特定 screen ?

  • 如果没有,有没有办法在不在 screen 本身运行命令的情况下查看某个 screen 的运行进程? (然后我就可以用kill了)

tl;dr 当我关闭 screen 时,正在运行的进程开始使用我所有的 cpu 并且不会终止。我希望它终止。

最佳答案

我自己做了解决方案。

简而言之,它找到 screen 进程并找到所有 java 进程,然后寻找其祖父进程是 screen 的 java 进程。

这是非常低效的,因为它为每个 screen 循环遍历数组。所以基本上是 O(n^2),但很少,所以它对我有用!

代码:

length=$(expr ${#screenName[@]} - 1)

# gets all of the java processes and their grand parents
# the reason is that the screen makes 2 processes one is the java process and the other is the parent process
# I can't grab a children in mac for some reason BUT i can grab the parent process
javaPs=()
javaGpPs=()
for javaId in $(pgrep java)
do
#echo
#echo $javaId
#echo $(ps -o ppid= $javaId)
#echo $(ps -o ppid= $(ps -o ppid= $javaId))
javaPs+=($javaId)
javaGpPs+=($(ps -o ppid= $(ps -o ppid= $javaId)))
done

echo "Child procressed followed by screen processes"
echo ${javaPs[@]}
echo ${javaGpPs[@]}
#gets the index of an element in an array
#search term is first followed by the array
#note that becuase it returns by echo you can not add any debug statements into this function
search() {
local i=1;
searchTerm="${1}"
shift #moves over the argument looking
array=("${@}") #grabs the rest of the args as an array (which is an array)
for str in ${array[@]}; do
if [ "$str" = "$searchTerm" ]; then
echo $((i - 1)) #should reference the correct index (0 to something)
return
else
((i++))
fi
done
echo "-1"
}

for (( i=0; i<=$length; i++ ))
do
#looks to see if there are multiple screens with the same name
for session in $(screen -ls | grep -o "[0-9]*\.${screenName[$i]}")
do
echo
echo "killing screen $session"
IFS='.' read -ra ADDR <<< "$session" #splits the id from the name
pid=${ADDR[0]}
screen -X -S "$session" quit # exit session

# now we kill the still running java process (because it will not exist for some reason)
itemIndex=$(echo $(search "${pid}" "${javaGpPs[@]}"))
javaId=${javaPs[$itemIndex]}
# the process that is being killed
echo "killing java process"
echo $(ps -p $javaId)
kill -9 $javaId
sleep 1
done
done

echo
echo "All process should now be dead doing extra clean up now"
screen -wipe #remove all dead screens

关于java - 杀死 screen 但java进程没有结束,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26434595/

38 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com