如何杀死屏幕会话中运行的特定进程,而不杀死该屏幕会话?

如何杀死屏幕会话中运行的特定进程,而不杀死该屏幕会话?

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

pstree -p <pid>

然后你就可以找到该进程的pid并将其杀死。

相关内容