1

I have run multiple ANN training processes under multiple screen sessions. When I enter a screen, I see a training process running.

Now, I want to kill a specific process inside the screen without killing the screen.

I can press CTRL + C. But, that produces some unwanted garbage text on the screen.

How can I do it cleanly?

If I try to kill the process using the process-ID, I become confused. For me, it is impossible to recognize individual processes. Coz, they are running files with the same file names.

How to do that?

N.B. I am using TensorFlow and Keras.

N.B.#2, I am using SSH.

5
  • Why is there "unwanted garbage" when you press CTRL+C?
    – aviro
    Dec 15, 2021 at 16:46
  • @aviro, that text is generated by TensorFlow.
    – user366312
    Dec 15, 2021 at 18:00
  • Then redirect stdout/err of your process to a file.
    – aviro
    Dec 15, 2021 at 18:57
  • 2
    Does Cntrl-C at least kill the process in addition to the garbage text? If so, is the garbage really that bad?
    – jwodder
    Dec 15, 2021 at 21:35
  • 1
    How do you start those screens? That changes what happens when you will the processes. Dec 16, 2021 at 1:09

2 Answers 2

3

If you are able to ssh in to the remote host (the one running screen), then you could modify my script from a similar question that I had to give you the pid of the process and then just kill it.

  1. Find the number of the window that you want to kill the process under. If you are viewing the window, Ctrl+a N will make it appear for a couple of seconds in the bottom left corner of the window.
    Note: That is hold Ctrl, press a, release Ctrl, then capital N
  2. If you have multiple screen sessions running, figure out which session you're targeting. I won't go into detail here, because I'm assuming that you're only running one session. You can check by running this on the remote host: screen -ls
  3. Run the modified script below, passing in the window number that you found in step 1.
    Note: you must save the script to a file and make it executable [chmod +x <script-name>] before you can run it [./<script-name> <window-number>])
  4. Double-check that what it returned looks like what was running on that window
  5. On the remote host, run kill <pid-from-first-column-that-script-returned> (replacing the brackets with the actual pid returned by the script)
  6. You're done!

The modified script:

#!/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

0

Each screen has a pid that you can get from the screen's name (pid.tty.hostor pid.sessionname). If all the processes are local (meaning, if you haven't connected from the screen session to remote host via ssh, for instance), it's easy to see the children of the screen using:

pstree -p <pid>

Then you can find the pid of the process and kill it.

2
  • all of them are SSH sessions.
    – user366312
    Dec 15, 2021 at 18:00
  • 1
    @user366312 That makes it more difficult. You won't be able to kill the process from the source host, only from the remote host. You can try following the port of the process to the remote host, find the correlated port and process on the remote host, run pstree... It's much easier to just press ctrl-c.
    – aviro
    Dec 15, 2021 at 18:59

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .