여러 세션에서 여러 인공 신경망 훈련 프로세스를 실행했습니다 screen
. 화면에 들어가면 훈련 과정이 실행되는 것을 볼 수 있습니다.
이제 화면을 종료하지 않고 화면 내부의 특정 프로세스를 종료하고 싶습니다.
를 누를 수는 CTRL + C
있지만 이로 인해 화면에 원치 않는 정크 텍스트가 생성됩니다.
어떻게 하면 깔끔하게 할 수 있나요?
프로세스 ID를 사용하여 프로세스를 종료하려고 하면 혼란스러워집니다. 나에게는 단일 프로세스를 식별하는 것이 불가능합니다. 동일한 파일 이름을 가진 파일을 실행하고 있기 때문입니다.
어떻게 하나요?
참고 저는 TensorFlow와 Keras를 사용하고 있습니다.
참고 #2, 저는 SSH를 사용하고 있습니다.
답변1
원격 호스트(실행 화면)에 SSH로 연결할 수 있으면 수정할 수 있습니다.내 스크립트는 내가 겪었던 비슷한 문제에서 비롯되었습니다.프로세스의 pid를 제공하고 종료합니다.
- 프로세스를 종료하려는 창 번호를 찾으십시오. 창을 보고 있는 경우
Ctrl+a N
창의 왼쪽 하단에 몇 초 동안 나타납니다.
노트:즉, Ctrl을 누른 상태에서 a를 누르고 Ctrl을 놓은 다음 대문자 N을 누릅니다. - 여러 화면 세션을 실행하는 경우 어떤 세션을 대상으로 삼고 있는지 알아보세요. 한 세션만 실행한다고 가정하고 여기에서는 자세히 설명하지 않겠습니다. 원격 호스트에서 다음 명령을 실행하여 이를 확인할 수 있습니다.
screen -ls
- 아래 수정된 스크립트를 실행하여 1단계에서 찾은 창 번호를 전달하세요.
노트:스크립트를 파일에 저장하고 실행 가능하게 만들어야 합니다. [chmod +x <script-name>
] 실행하기 전에 [./<script-name> <window-number>
]) - 반환된 내용이 해당 창에서 실행 중인 내용과 유사한지 다시 확인하세요.
- 원격 호스트에서 다음을 실행합니다
kill <pid-from-first-column-that-script-returned>
(대괄호를 스크립트에서 반환된 실제 pid로 바꿉니다). - 이제 끝났습니다!
수정된 스크립트:
#!/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를 찾아서 종료할 수 있습니다.