How to detect the number of opened terminals by the user
Solution 1
If you really need to get the number of terminal you have open, go for counting the files owned by you under /dev/pts
(although this might include ones opened by background processes, not by graphical terminal emulators). Alternatively, count the number of child processes of your terminal emulator(s), as shown by Jacob in the first line of his response.
Avoid relying on who
's output, and looking for gnome-pty-helper
processes, since these don't work in newer gnome-terminal
versions.
Note that nowadays pretty much all graphical terminal emulators (including putty) and multiplexers (screen, tmux) support 256 colors. You can get really nice colored prompts if you use this palette.
My recommendation for a very simple solution is to base the color on the current tty line's number. E.g. process the output of the tty
command to take the number only and derive the color from that. A certain tty line number is only given to one terminal at a time, you'd have to close that terminal first before the same line number is reissued by the kernel. This, combined with 256 colors, automatically guarantees that you won't see the same color twice at a given time (and even with 16 colors it'd give a quite even distribution). No need for maintaining a global counter, and no need for counting terminals or processes.
Solution 2
In a single user situation, if we take the example of xterm
, we can simply count the number of pids of xterm
; xterm
creates a separate pid for each and every window.
gnome-terminal
however runs a single pid, but the good news is that it creates a child process for each and every window and/or tab. we can retrieve these child processes by the command:
pgrep -P <pid_of_gnome-terminal>
There are however a few complications to deal with:
Reading your question, we may assume, that user in this case is actually owner of the x-session. Usually we can simply use the
$USER
-variable, but this might not match the currently logged in user of$DISPLAY
.In a multi-user situation, pids belonging to the (either which) terminal application, do not necessarily belong to the current
$DISPLAY
. We need to split off only the relevant pids and child-pids.On Unity (15.10 or lower), if a second user logs in, an additional process is started (
gnome-pty-helper
), which appears as a child process ingnome-terminal
, but the process (obviously) has no window or tab. On Mate, the process exists anyway.
In short
To count the number of tabs and/or windows of a terminal application, we need to:
- See if we run a terminal application which has multiple pids or a single pid on one
$DISPLAY
(x-session) - From the running processes, split off only the relevant pids, running on this
$DISPLAY
- If the application runs child-processes for its pid (for windows/tabs), see if
gnome-pty-helper
runs, to correct the number.
This can very well be scripted however, to reliably find the number of currently opened windows and/or tabs.
The script
In the script below, the targeted terminal application is used as an argument. The script works on many terminals I tested it on. An exception is Tilda
at this moment.
An example
- I have two users logged in, one (not the current) with two
gnome-terminal
windows, one (the one in the image) with threegnome-terminal
windows, and twoxterm
windows.
The command:
/path/to/get_terms.sh gnome-terminal
outputs:
3
while
/path/to/get_terms.sh xterm
outputs:
2
The script
#!/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
To use
-
Copy the script into an empty file, save it as
get_terms.sh
, make it executable and run it by the command:/path/to/get_terms.sh <terminal_application>
Solution 3
An awk
way:
who | awk 'BEGIN{count=0}{ if(NR!=1){count++} }END{print count}'
Explanation:
In above 1 liner command, awk
is used to find the count of terminal.
Inside awk
program, it is just checking the number of lines return by who command - 1.
Related videos on Youtube
manav m-n
Please note that this profile is outdated and kept here only for historical reasons. Name: Unknown Location: Unknown Education: Unknown Facebook/Twitter/Instagram: None
Updated on September 18, 2022Comments
-
manav m-n over 1 year
I am using Ubuntu and can manually change the
bash
shell prompt color to green usingexport PS1="\e[0;32m[\u@\h \W]\$ \e[m"
However, I want the shell prompt color to automatically change whenever I open a new terminal or tab. I am aware that the basic tty TERM has 16 colors, and it's okay to rotate the colors if more than 16 terminals are open. Will the solution also work when I connect through
Putty
,tmux
orscreen
.My idea is to write a shell script and place it in
.bashrc
which detects the new terminal session the user has opened and increment a global counter from\e[0;31m[
to\e[0;47m[
. How to detect the number of opened terminals by the user? -
GreggD almost 8 yearsThis one works very nice for my mate-terminal & xterm, seems bullet-proof.
-
GreggD almost 8 yearsBeautiful idea with
tty
. I guess we/others have concentrated too much on that "question" and forgot that there might be other solutions for entire "need" :) I would even play with implementing random color selector. If it's 256 colors, selecting same/similar colors should not happen much. However manually setting colors for given pts numbers will give better personalization. -
egmont almost 8 years@TedM. Yes the question was pretty much phrased as an XY question, along the lines of: "I wish to have different color in each terminal, so tell me: how do I count the number of terminals?"
-
egmont almost 8 years@TedM. Random is also a nice idea! (One property of a deterministic mapping is that after sudoing the new user might easily set the same prompt color. This may or may not what the original asker wants to have.)
-
GreggD almost 8 yearsRandomizer is quite easy:
color="\e[38;5;"$(((RANDOM % 231 )+1))"m"
(only 231 to reject greyscale), however many of those colors happened to be just different shades and couple of those are dark so might be almost invisible and I guees nobody will use that in real life... -
GreggD almost 8 yearsRight here I always have one
gnome-pty-helper
running, even when there's only one user logged-in (right after reboot) and when I open any amount of terminals it runs second, same helper. Your new script seems to be working for mate-terminal (wasn't able to cause that zero-thing), but with xterm, when I have only 1 opened it shows0
and starts showing good number only after second one and with gnome-terminal it always shows one too less (outputing0
when only one is opened). -
egmont almost 8 yearsWe don't know the asker's Ubuntu version. In 16.04 there is definitely no gnome-pty-helper anymore (git.gnome.org/browse/vte/commit/?id=299c700). I'm not going to downgrade to check the exact process hierarchy in older versions. I know there used to be such process, I'm just not entirely sure how the parent-child hierarchy looked like. By the way, I took the child-process-count idea from your original response, so I don't understand that "(also by you)", nevermind.
-
Jacob Vlijm almost 8 years@TedM. Thanks, that is useful information, fixed now.
-
GreggD almost 8 yearsI really admire your "passion" :) ... but there's still a problem with gnome-terminal. One gives 1, two gives 1, three gives 2, four gives 3, etc.. Plus my new discovery, MATE's "Tilda" (that one extra "unknown" terminal in my answer) also have same issue as gnome-terminal, but with it's tabs. xterm and mate-terminal seems to be working fine though.
-
Jacob Vlijm almost 8 years@TedM. Thanks for mentioning! Silly question, but are you sure you use the latest code? On Mate 15.10 all test I run work without exception. What is your Mate version? On Unity everything already worked fine.
-
Jacob Vlijm almost 8 years@TedM. Also on my pretty blank 15.10 Mate, it is there by default. Just re- ran the tests, perfectly! could I ask you tomorrow or so to run an edited version of the script and post the output somewhere, to see what causes the exception in your case?
-
Jacob Vlijm almost 8 yearsLet us continue this discussion in chat.
-
muru almost 8 yearsConcisely:
who | awk 'END{print NR - 1}'
, since what you want is number of lines - 1. -
Jacob Vlijm almost 8 yearsSince OP wants to use the outcome to automatically set the terminal color(s), this seems not a really relevant option.
-
NonStandardModel almost 8 yearsSorry I see now he wants to use it in script. But then would ps -ef | grep UserName | grep bash | grep -v grep | wc -l not work?
-
manav m-n almost 8 years@egmont: may you also explain why
who
output is unreliable