如何检测用户打开的终端数量

如何检测用户打开的终端数量

我正在使用 Ubuntu,可以手动将bashshell 提示符颜色更改为绿色的使用

export PS1="\e[0;32m[\u@\h \W]\$ \e[m" 

但是,我希望每次打开新终端或选项卡时,shell 提示符颜色都会自动更改。我知道基本 tty TERM 有 16 种颜色,如果打开了超过 16 个终端,可以旋转颜色。当我通过 、 或 连接时,该解决方案是否Puttytmux有效screen

我的想法是编写一个 shell 脚本并将其放置在.bashrc检测用户打开的新终端会话中,并将全局计数器从 增加到\e[0;31m[\e[0;47m[如何检测用户打开的终端数量?

答案1

如果您确实需要获取已打开的终端数量,请计算您拥有的文件数量/dev/pts(尽管这可能包括由后台进程打开的文件,而不是由图形终端仿真器打开的文件)。或者,计算终端仿真器的子进程数量,如 Jacob 在其回复的第一行中所示。

避免依赖who的输出并寻找流程,因为这些在新版本gnome-pty-helper中不起作用。gnome-terminal

请注意,如今几乎所有图形终端仿真器(包括 putty)和多路复用器(screen、tmux)都支持 256 种颜色。如果您使用此调色板,您可以获得非常漂亮的彩色提示。

我推荐一个非常简单的解决方案,即根据当前 tty 行号来确定颜色。例如,处理命令的输出tty以仅获取数字并从中得出颜色。某个 tty 行号一次只能分配给一个终端,您必须先关闭该终端,然后内核才能重新发出相同的行号。这与 256 种颜色相结合,自动保证您不会在给定时间内看到两次相同的颜色(即使使用 16 种颜色,也会给出相当均匀的分布)。无需维护全局计数器,也无需计数终端或进程。

答案2

在单用户情况下,如果我们以 为例xterm,我们可以简单地计算 的 pid 数量xtermxterm为每个窗口创建一个单独的 pid。
gnome-terminal但是运行单个 pid,但好消息是它为每个窗口和/或选项卡创建一个子进程。我们可以通过以下命令检索这些子进程:

pgrep -P <pid_of_gnome-terminal>

然而,还有一些复杂问题需要处理:

  • 阅读你的问题,我们可以假设,用户在这种情况下实际上是x-session 的所有者。通常我们可以简单地使用$USER-变量,但这可能与 的当前登录用户不匹配$DISPLAY

  • 在多用户情况下,属于(任一)终端应用程序的 pid 不一定属于当前$DISPLAY。我们只需要分离相关的 pid 和子 pid。

  • 在 Unity(15.10 或更低版本)中,如果第二个用户登录,则会启动一个附加进程(gnome-pty-helper),该进程在 中显示为子进程gnome-terminal,但该进程(显然)没有窗口或选项卡。伴侣,无论如何该过程都存在。

简而言之

要计算终端应用程序的选项卡和/或窗口的数量,我们需要:

  • 查看我们是否运行具有多个 pid 的终端应用程序或者$DISPLAY一个(x-session)上的单个 pid
  • 从正在运行的进程中分离出来仅有的相关的 pid,在此上运行$DISPLAY
  • 如果应用程序为其 pid(对于窗口/选项卡)运行子进程,则查看是否gnome-pty-helper运行,以更正数字。

然而,这可以很好地编写脚本,以可靠地找到当前打开的窗口和/或选项卡的数量。

剧本

在下面的脚本中,目标终端应用程序被用作争论。我测试过该脚本在许多终端上都能运行。但Tilda目前有一个例外。

一个例子

  • 我有两个用户登录,一个(不是当前用户)有两个gnome-terminal窗口,一个(图像中的用户)有三个gnome-terminal窗口,还有两个xterm窗口。

在此处输入图片描述

命令:

/path/to/get_terms.sh gnome-terminal

输出:

3

尽管

/path/to/get_terms.sh xterm

输出:

2

剧本

#!/bin/bash

terminal=$1

# get the user running the current x-session
username=$(who | grep $DISPLAY | head -1 | awk '{print $1}')
# get the pid of the terminal for the current user
userpid=$(pgrep -u $username $terminal)
# check what type the terminal is (multi pid/single pid)
npids="$(echo "$userpid" | wc -w)"
# in case of a single pid, count the children
if [ "$npids" -eq 1 ]; then
  # check if gnome-pty-helper runs (starts when multiple users are logged in)
  ptpid=$(pgrep gnome-pty-helpe)
  # get number of child- procs
  let "orig = $( pgrep -P $(pgrep -u $username $terminal) | wc -w )" 
  # if pty-helper runs, correct the number of child procs
  if [ -n "$ptpid" ] && [ -n "$userpid" ]; then
    let "n_terms = $orig-1"; else let "n_terms = $orig"
  fi
  # if no child procs run, n-terminals = n-counted pids (difference Mate <> Unity)
  if [ "$n_terms" -eq 0 ]; then echo $orig; else echo $n_terms; fi
# in case of multiple pids, count the pids
elif [ "$npids" -gt 1 ]; then echo $npids
fi

使用

  • 将脚本复制到一个空文件中,另存为get_terms.sh,使其可执行并通过以下命令运行它:

    /path/to/get_terms.sh <terminal_application>
    

答案3

一种awk方法:

who | awk 'BEGIN{count=0}{ if(NR!=1){count++} }END{print count}'

解释:

上面的 1 行命令awk用于查找终端的数量。在awk程序内部,它只是检查 who 命令返回的行数 - 1。

答案4

简单的方法可能只是运行System Monitor(如果从终端启动,则必须写入gnome-system-monitor)并在“进程”选项卡下按名称排列正在运行的进程,然后计算列表中出现的次数Bash(如果您按名称排列,它们将全部在一起,因此很容易计算)。

请注意,如果您想查看用户打开的终端数量,则必须查找Bash而不是查找。一旦您打开终端,它也会出现在进程列表中,但即使打开了更多终端,它也只会保留一个。中的“查看”按钮允许您设置要查看的进程,例如所有进程/用户进程/活动...Gnome TerminalGnome TerminalSystem Monitor

相关内容