我在多个会话下运行了多个人工神经网络训练过程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,您可以从屏幕名称(pid.tty.host
或pid.sessionname
)中获取该 pid。如果所有进程都是本地的(例如,如果您尚未通过 屏幕会话连接到远程主机ssh
),则可以使用以下命令轻松查看屏幕的子进程:
pstree -p <pid>
然后你就可以找到该进程的pid并将其杀死。