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


9

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

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

但是,我希望每次打开新的终端或选项卡时,外壳提示颜色都将自动更改。我知道基本的tty TERM有16种颜色,如果打开的端子超过16种,则可以旋转颜色。会当我连接通过溶液也行Puttytmuxscreen

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

Answers:


8

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

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

请注意,当今几乎所有图形终端仿真器(包括腻子)和多路复用器(屏幕,tmux)都支持256种颜色。如果使用此调色板,您会得到非常漂亮的彩色提示。

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


1
与美丽的主意tty。我猜我们/其他人对这个“问题”的关注太多了,却忘记了整个“需求”可能还有其他解决方案:)我什至会玩实现随机颜色选择器。如果是256色,选择相同/相似的颜色应该不会太多。但是,为给定的磅值数字手动设置颜色将提供更好的个性化设置。
GreggD

@TedM。是的,这个问题在很大程度上是作为XY问题来表达的:“我希望每个端子具有不同的颜色,所以告诉我:我如何计算端子的数量?”
egmont

@TedM。随机也是一个好主意!(确定性映射的一个属性是,在对新用户打了喷嚏之后,可能会轻松地设置相同的提示颜色。这可能会也可能不会是原始申请者想要的颜色。)
例如,2016年

1
随机化器很容易:(color="\e[38;5;"$(((RANDOM % 231 )+1))"m"只有231个可以拒绝灰度级),但是其中许多颜色恰好是不同的阴影,而其中的一些则是深色的,因此可能几乎看不见,我猜没有人会在现实生活中使用它
GreggD

我们不知道问问者的Ubuntu版本。在16.04中肯定不再有gnome-pty-helper(git.gnome.org/browse/vte/commit/?id=299c700)。我不会降级以检查旧版本中的确切流程层次结构。我知道曾经有过这样的过程,但我不完全确定父子层次结构是什么样子。顺便说一句,我从您最初的回答中采纳了子进程计数的想法,所以我不明白“(也是您的)”,没关系。
egmont

5

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

pgrep -P <pid_of_gnome-terminal>

但是,有一些复杂的情况要处理:

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

  • 在多用户情况下,属于(哪个)终端应用程序的pid不一定属于current $DISPLAY。我们只需要拆分相关的pid和child pid。

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

简而言之

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

  • 查看我们是否运行一个终端应用程序,该应用程序在一个应用程序上具有多个pid 一个pid $DISPLAY(x会话)
  • 从正在运行的进程中,分割出相关的pid,然后在此进程上运行$DISPLAY
  • 如果应用程序为其pid运行子进程(对于Windows / tab),请查看是否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>

在这里gnome-pty-helper,即使只有一个用户登录(重新启动后立即登录),当我打开任意数量的终端时,它总是运行一个助手,而我总是在运行一个助手。您的新脚本似乎适用于mate-terminal(无法导致零值),但是使用xterm时,当我只有1个打开时,它显示0并仅在第二个之后和gnome-terminal才开始显示良好的数字它总是显示得太少(0仅打开一个时输出)。
GreggD

@TedM。谢谢,这是有用的信息,现已修复。
雅各布·弗利姆

我真的很佩服您的“热情” :) ...但是gnome-terminal仍然存在问题。一给一,二给一,三给二,四给三,依此类推。再加上我的新发现,MATE的“ Tilda”(我的答案中还有一个“未知”终端)也与gnome-terminal有相同的问题,但是它的标签。xterm和mate-terminal似乎工作正常。
GreggD '16

@TedM。感谢您的提及!愚蠢的问题,但是您确定使用最新的代码吗?在Mate 15.10上,所有测试我都正常运行。您的伴侣是什么版本?在Unity上,一切都已经正常运行。
雅各布·弗利姆

@TedM。同样在我漂亮的空白15.10 Mate上,默认情况下也存在。完美地重新运行测试!我明天可以问您一个运行脚本的编辑版本并将输出发布到某处,以查看导致您的情况异常的原因吗?
雅各布·弗利姆

1

一种awk方式:

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

说明:

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


这对我来说返回0,这显然是不正确的……
Zanna

这对我的mate-terminal和xterm来说非常好用,似乎是防弹的。
GreggD

简而言之:who | awk 'END{print NR - 1}',因为您想要的是行数
-1。– muru

0

一种简单的方法也可能只是运行System Monitor(如果要从Terminal启动,则必须编写gnome-system-monitor),然后在“ Processes”选项卡下按Name排列正在运行的进程,然后计算Bash列表中出现的次数(如果按名称,因此很容易计算)。

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


由于OP希望使用结果自动设置终端颜色,因此这似乎不是一个真正相关的选项。
雅各布·弗利姆

抱歉,我现在看到他想在脚本中使用它。但是,然后ps -ef | grep用户名| grep bash | grep -v grep | wc -l不起作用?
NonStandardModel
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.