自动循环(关闭)所有屏幕会话的方法

自动循环(关闭)所有屏幕会话的方法

当我登录到我可以访问的超级计算机的交互节点时,我经常使用屏幕 - 我经常运行程序然后继续。我可以登录大约 20 个单独的节点;如果我检查其中任何一个,我将有大约 4 个分离的会话。每个会话中可能都有 5 个屏幕会话。

如果它们没有运行任何进程,是否有一种快速方法可以循环浏览所有这些并关闭它们?我当前的进程是screen -ls,然后screen -r ####输入exit,直到我回到基本屏幕。

编辑

这是我根据 Thor 的回答编写的脚本:

for screen_pid in $(screen -ls | sed -nr 's/^\t+([0-9]+).*/\1/p');
do 
  for shell_tty in $(ps h --ppid $screen_pid -o tty);
  do
    number_of_processes=$(ps a -o tty | grep $shell_tty | wc -l)
    if (( number_of_processes > 1 )); then 
      echo number $number_of_processes
    else
      # screen -S $screen_pid -X kill  
      screen -S $screen_pid -X quit
    fi
  done
done

当我使用 kill 运行它时,会话似乎没有发生任何事情。当我使用 quit 运行时,它似乎会终止整个会话以及其中运行的任何内容(而不检查是否有进程正在运行)。从这里开始调整?

答案1

一种选择是将程序作为屏幕主命令运行,然后屏幕将在完成后退出。

如果上述方法没有用,您可以通过查看连接到 shell tty 的进程数来估计正在运行的进程数。

需要几个习语

从以下位置提取屏幕 pid screen -ls

screen -ls | sed -nr 's/^\t+([0-9]+).*/\1/p'

查找谁拥有该 pid 作为父级:

ps h --ppid $screen_pid -o tty

查看有多少个进程连接到该 tty:

ps a -o tty | grep $shell_tty | wc -l

综合起来

screen -ls | sed -nr 's/^\t+([0-9]+).*/\1/p' | while read screen_pid; do
  shell_tty=$(ps h --ppid $screen_pid -o tty)
  number_of_processes=$(ps a -o tty | grep $shell_tty | wc -l)
  if (( number_of_processes > 1 )); then
    # more than the shell is running
  else
    # can be killed
  fi
done

相关内容