2014-10-17 2 views
2

Я запускаю скрипт, который в основном запускает кучу серверов для локального тестирования.убийственный экран, но процесс java не заканчивается

Эти банки работают на разных экранах, потому что им необходимо независимо принимать ввод с клавиатуры. Для этого я использовал экран.

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 

Он отлично работает на экраны убивают. НО, второй, я делаю, что java внезапно занимает 100% моего процессора.

Перед тем, как использовать бросить команду экрана

The servers running normally

После я использую экран командной бросить

enter image description here

Они также принимают навсегда, чтобы убить через помощью силы графического интерфейса бросить

enter image description here

Дополнительная информация:

  • серверы используют Jetty, которые работают на одном Java нить. а затем другой поток просто сидит и ждет ввода клавиатуры.
  • Очевидно, что это работает на mac, а скрипт находится в bash, поэтому я бы хотел, чтобы bash-решение работало для mac и linux.
  • Кроме того, они построены с использованием Java 7, но работать с использованием Java 8

, поскольку серверы принимают ввод с клавиатуры все команды, посылаемые на экран поглощаются серверов. У них есть вход, который завершает работу, но я не хочу доверять серверам, чтобы они ушли.

Так что мои вопросы:

  • Есть ли способ, чтобы иметь экран прекратить все запущенные процессы в нем, когда он заканчивается?

  • Если нет способа отправить ctrl-c на конкретный экран?

  • Если нет способа узнать, что работает на определенном экране без запуска команд на самом экране? (Тогда я могу просто использовать убийство)

Т.Л., Др, когда я убиваю экран запущенный процесс начинает использовать весь мой процессор и не прекращается. Я хочу, чтобы он закончил.

+2

Вы могли бы убить каждую программу Java, вызвав 'killall -9 java'. – Tom

+0

Хорошо, хорошо, что я буду использовать в качестве наихудшего решения, поскольку он убивает любые другие программы java, которые у меня есть ... Но это мешает мне играть в миниатюру, когда я должен работать: P Но, надеюсь, решение, которое только приходит на ум. :) – dtracers

+1

Если вы найдете способ определить идентификатор процесса вашего 'screen' (или даже лучше сохранить их при их появлении), вы можете использовать опцию' -ppid' 'ps' для уничтожения всех процессов порожденных процессами 'screen'. –

ответ

1

Сделано решение самостоятельно.

В двух словах он находит процесс отображения экрана и находит все процессы java, а затем ищет java-процесс, процесс дедушки которого - это экран.

Это чрезвычайно неэффективно, поскольку оно проходит через массив для каждого экрана. Так что в основном 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