Как определить количество открытых терминалов пользователем

Я использую Ubuntu и могу вручную изменить цвет приглашения оболочки bash на зеленый с помощью

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

Однако я хочу, чтобы цвет подсказки оболочки автоматически менялся, когда я открываю новый терминал или вкладку , Я знаю, что базовый tty TERM имеет 16 цветов, и нормально поворачивать цвета, если открыто более 16 терминалов. Будет ли решение работать, когда я подключусь через Putty, tmux или screen.

Моя идея - написать сценарий оболочки и поместить его в .bashrc, который определяет новый сеанс терминала пользователь открыл и увеличил глобальный счетчик с \e[0;31m[ до \e[0;47m[. Как определить количество открытых терминалов пользователем?

1
задан 1 June 2016 в 20:15

3 ответа

В ситуации с одним пользователем, если взять пример xterm, мы можем просто подсчитать количество pids из xterm; xterm создает отдельный pid для каждого окна. gnome-terminal однако запускает один pid, но хорошей новостью является то, что он создает дочерний процесс для каждого окна и / или вкладки. мы можем восстановить эти дочерние процессы с помощью команды:

pgrep -P <pid_of_gnome-terminal>

Однако есть несколько осложнений:

Считая ваш вопрос, мы можем предположить, что пользователь в этом случае фактически является владельцем x-сессии. Обычно мы можем просто использовать $USER -variable, но это может не соответствовать зарегистрированному в данный момент пользователю $DISPLAY. В многопользовательской ситуации pids, принадлежащие терминальному приложению (или который), необязательно относятся к текущему $DISPLAY. Нам нужно отделить только соответствующие pids и child-pids. В Unity (15.10 или ниже), если второй пользователь входит в систему, запускается дополнительный процесс (gnome-pty-helper), который появляется как дочерний процесс в gnome-terminal, но процесс (очевидно) не имеет окна или вкладки. В Mate процесс все равно существует.

Короче

Чтобы подсчитать количество вкладок и / или окон терминального приложения, нам необходимо:

Читая ваш вопрос, мы может предположить, что пользователь в этом случае фактически является владельцем x-сессии. Обычно мы можем просто использовать $USER -variable, но это может не соответствовать зарегистрированному пользователю $DISPLAY. Из запущенных процессов отделяются только соответствующие pids, работающие на этом $DISPLAY В многопользовательской ситуации pids, принадлежащие терминальному приложению (или который), необязательно относятся к текущему $DISPLAY. Нам нужно отделить только соответствующие pids и child-pids.

Это может быть очень хорошо написано, чтобы надежно найти количество открываемых в настоящее время окон и / или вкладок.

Сценарий

В приведенном ниже сценарии целевое приложение терминала используется в качестве аргумента. Скрипт работает на многих терминалах, на которых я тестировал его. Исключением является Tilda в этот момент.

Пример

Из запущенных процессов отделяются только соответствующие pids, работающие на этом $DISPLAY [!d18 ]

Команда:

/path/to/get_terms.sh gnome-terminal

выходы:

3

, а

/path/to/get_terms.sh xterm
[d36 ]:

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

Использовать

Считая ваш вопрос, мы можем предположить, что пользователь в этом случае фактически является владельцем x-сессии. Обычно мы можем просто использовать $USER -переменная, но это может не соответствовать зарегистрированному пользователю $DISPLAY.

/path/to/get_terms.sh <terminal_application>
5
ответ дан 23 May 2018 в 10:56
  • 1
    Прямо здесь у меня всегда работает один gnome-pty-helper, даже если во время входа в систему только один пользователь (сразу после перезагрузки), и когда я открываю любое количество терминалов, он выполняет второй, тот же помощник. Ваш новый скрипт, похоже, работает на mate-terminal (не смог вызвать нулевое значение), но с xterm, когда у меня только 1, он показывает 0 и начинает показывать хорошее число только после второго и с gnome-terminal, он всегда показывает один слишком низкий (вывод 0 при открытии только одного). – GreggD 21 May 2016 в 00:23
  • 2
    @TedM. Спасибо, это полезная информация, исправленная сейчас. – Jacob Vlijm 21 May 2016 в 08:21
  • 3
    Я действительно восхищаюсь вашей «страстью». :) ... но проблема с gnome-terminal еще не решена. Один дает 1, два дает 1, три дает 2, четыре дает 3 и т. Д. Кроме того, мое новое открытие, MATE's 'Tilda " (что один дополнительный «неизвестный» терминал в моем ответе) также имеет ту же проблему, что и gnome-terminal, но с его вкладками. Однако xterm и mate-terminal работают нормально. – GreggD 21 May 2016 в 23:18
  • 4
    @TedM. Благодарим за упоминание! Глупый вопрос, но уверены ли вы, что используете последний код? На Mate 15.10 все тесты запускаются без исключения. Какова ваша версия Mate? На Unity все работало нормально. – Jacob Vlijm 21 May 2016 в 23:30
  • 5
    @TedM. Также на мой довольно пустой 15.10 Mate, он есть по умолчанию. Просто повторил тесты, отлично! могу я спросить вас завтра или около того, чтобы запустить отредактированную версию сценария и опубликовать вывод где-нибудь, чтобы узнать, что вызывает исключение в вашем случае? – Jacob Vlijm 21 May 2016 в 23:36

Способ awk:

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

Объяснение:

В команде выше 1 liner awk используется, чтобы найти счетчик терминалов. Внутри программы awk он просто проверяет количество строк, возвращаемых командой who - 1.

1
ответ дан 23 May 2018 в 10:56
  • 1
    это возвращает 0 для меня, что явно неверно ... – Zanna 20 May 2016 в 09:37
  • 2
    Это работает очень хорошо для моего mate-terminal & amp; xterm, кажется пуленепробиваемым. – GreggD 20 May 2016 в 09:56
  • 3
    Вкратце: who | awk 'END{print NR - 1}', так как вам нужно количество строк - 1. – muru 22 May 2016 в 20:12

Простым способом может быть просто запуск System Monitor (если он начат с терминала, вы должны написать gnome-system-monitor), а на вкладке «Процессы» упорядочить запущенные процессы по имени и подсчитать количество вхождений Bash в листинг (они будут все вместе, если вы организуете по имени, поэтому их легко подсчитать).

Обратите внимание, что вы должны искать Bash, а не для Gnome Terminal, если хотите видеть количество открытых терминалов пользователем. Как только вы откроете терминал Gnome Terminal, также появится в списке «Процессы», но останется только одним, даже если открыто больше терминалов. Кнопка «Просмотр» в System Monitor позволяет вам установить, какие процессы увидеть, например. Все процессы / пользовательские процессы / активные ...

0
ответ дан 23 May 2018 в 10:56
  • 1
    Поскольку OP хочет использовать результат, чтобы автоматически установить цвет (ы) терминала, это кажется не очень подходящим вариантом. – Jacob Vlijm 28 May 2016 в 00:07
  • 2
    Извините, я вижу, теперь он хочет использовать его в скрипте. Но тогда будет ps -ef | grep UserName | grep bash | grep -v grep | wc -l не работает? – NonStandardModel 28 May 2016 в 00:34

Другие вопросы по тегам:

Похожие вопросы: