Screen 세션을 종료하지 않고 Screen 세션 내에서 실행 중인 특정 프로세스를 종료하려면 어떻게 해야 합니까?

Screen 세션을 종료하지 않고 Screen 세션 내에서 실행 중인 특정 프로세스를 종료하려면 어떻게 해야 합니까?

여러 세션에서 여러 인공 신경망 훈련 프로세스를 실행했습니다 screen. 화면에 들어가면 훈련 과정이 실행되는 것을 볼 수 있습니다.

이제 화면을 종료하지 않고 화면 내부의 특정 프로세스를 종료하고 싶습니다.

를 누를 수는 CTRL + C있지만 이로 인해 화면에 원치 않는 정크 텍스트가 생성됩니다.

어떻게 하면 깔끔하게 할 수 있나요?

프로세스 ID를 사용하여 프로세스를 종료하려고 하면 혼란스러워집니다. 나에게는 단일 프로세스를 식별하는 것이 불가능합니다. 동일한 파일 이름을 가진 파일을 실행하고 있기 때문입니다.

어떻게 하나요?

참고 저는 TensorFlow와 Keras를 사용하고 있습니다.

참고 #2, 저는 SSH를 사용하고 있습니다.

답변1

원격 호스트(실행 화면)에 SSH로 연결할 수 있으면 수정할 수 있습니다.내 스크립트는 내가 겪었던 비슷한 문제에서 비롯되었습니다.프로세스의 pid를 제공하고 종료합니다.

  1. 프로세스를 종료하려는 창 번호를 찾으십시오. 창을 보고 있는 경우 Ctrl+a N창의 왼쪽 하단에 몇 초 동안 나타납니다.
    노트:즉, Ctrl을 누른 상태에서 a를 누르고 Ctrl을 놓은 다음 대문자 N을 누릅니다.
  2. 여러 화면 세션을 실행하는 경우 어떤 세션을 대상으로 삼고 있는지 알아보세요. 한 세션만 ​​실행한다고 가정하고 여기에서는 자세히 설명하지 않겠습니다. 원격 호스트에서 다음 명령을 실행하여 이를 확인할 수 있습니다.screen -ls
  3. 아래 수정된 스크립트를 실행하여 1단계에서 찾은 창 번호를 전달하세요.
    노트:스크립트를 파일에 저장하고 실행 가능하게 만들어야 합니다. [ chmod +x <script-name>] 실행하기 전에 [ ./<script-name> <window-number>])
  4. 반환된 내용이 해당 창에서 실행 중인 내용과 유사한지 다시 확인하세요.
  5. 원격 호스트에서 다음을 실행합니다 kill <pid-from-first-column-that-script-returned>(대괄호를 스크립트에서 반환된 실제 pid로 바꿉니다).
  6. 이제 끝났습니다!

수정된 스크립트:

#!/bin/bash
# Accept a GNU/screen window number and return the process running in its shell. 
# It assumes that you only have 1 session. If you have multiple sessions,
# pass in session name as the second argument.
TargetTabNum=$1
SessionName=$2

if [ -z "$SessionName" ]; then
    SessionName=.*
fi

# This finds the session PID given the session name.
# The screen command prints the list of session IDs
# Example output of screen command:
#     There is a screen on:
#             29676.byobu     (12/09/2019 10:23:19 AM)        (Attached)
#     1 Socket in /run/screen/S-{username here}.
# Example output after sed command: 29676
SessionPID=$(screen -ls | sed -n "s/\s*\([0-9]*\)\.$SessionName\t.*/\1/p")

# This gets all the processes that have the session as a parent,
# loops through them checking the WINDOW environment variable for
# each until it finds the one that matches the window number, and
# then finds the process with that process as a parent and prints its
# pid, command, and arguments (or null if there are no matching processes)
ProcessArray=( $(ps -o pid --ppid $SessionPID --no-headers) )
for i in "${ProcessArray[@]}"
do
    ProcTabNum=$(tr '\0' '\n' < /proc/$i/environ | grep ^WINDOW= | cut -d '=' -f2)
    if [ ! -z "$ProcTabNum" ] && [ "$TargetTabNum" -eq "$ProcTabNum" ]; then
        ProcInTab=$(ps -o pid,args --ppid $i --no-headers)
        if [[ $? -eq 1 ]]; then
            ProcInTab=NULL
        fi
        echo $ProcInTab
        exit 0
    fi
done
echo "Couldn't find the specified Tab: $TargetTabNum" >&2
exit 1

답변2

각 화면에는 화면 이름( pid.tty.host또는 pid.sessionname)에서 얻을 수 있는 pid가 있습니다. 모든 프로세스가 로컬인 경우(예: screen 세션을 통해 원격 호스트에 연결되지 않은 경우 ssh) 다음을 사용하여 screen의 하위 프로세스를 쉽게 볼 수 있습니다.

pstree -p <pid>

그런 다음 프로세스의 pid를 찾아서 종료할 수 있습니다.

관련 정보