Screenセッションを終了せずにScreenセッション内で実行されている特定のプロセスを終了するにはどうすればよいですか?

Screenセッションを終了せずにScreenセッション内で実行されている特定のプロセスを終了するにはどうすればよいですか?

複数のセッションで複数の人工ニューラルネットワークトレーニングプロセスを実行しましたscreen。画面に入ると、トレーニングコースが実行されていることがわかります。

これで、画面を終了せずに画面内の特定のプロセスを終了したいと思います。

を押すことはできますが、CTRL + Cこれは画面に不要なジャンクテキストを生成します。

どうすればきれいにできますか?

プロセスIDを使用してプロセスを終了しようとすると混乱します。私にとっては、単一のプロセスを識別することは不可能です。同じファイル名のファイルを実行しているからです。

どうすればいいですか?

注私はTensorFlowとKerasを使用しています。

注#2、私はSSHを使用しています。

答え1

リモートホスト(実行画面)にSSHで接続できる場合は変更できます。私のスクリプトは、私が経験した同様の問題から来ました。プロセスのpidを提供して終了します。

  1. プロセスを終了するウィンドウ番号を見つけます。ウィンドウを見ている場合は、Ctrl+a Nウィンドウの左下に数秒間表示されます。
    メモ:つまり、Ctrlキーを押しながらaキーを押しながらCtrlキーを放し、大文字Nを押します。
  2. 複数の画面セッションを実行している場合は、どのセッションをターゲットにしているかを確認してください。 1つのセッションしか実行しないと仮定し、ここでは詳細に説明しません。リモートホストで次のコマンドを実行してこれを確認できます。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を見つけて終了できます。

関連情報