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

9

Я использую 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[. Как определить количество открытых терминалов пользователем?

Манав мн
источник

Ответы:

8

Если вам действительно нужно получить номер открытого терминала, перейдите к подсчету файлов, которыми вы владеете /dev/pts(хотя это может включать файлы , открытые фоновыми процессами, а не графическими эмуляторами терминала). В качестве альтернативы подсчитайте количество дочерних процессов вашего эмулятора (ов) терминала, как показано Джейкобом в первой строке его ответа.

Старайтесь не полагаться на whoвывод и искать gnome-pty-helperпроцессы, так как они не работают в более новых gnome-terminalверсиях.

Обратите внимание, что в настоящее время почти все графические эмуляторы терминала (включая putty) и мультиплексоры (screen, tmux) поддерживают 256 цветов. Вы можете получить действительно красивые цветные подсказки, если используете эту палитру.

Моя рекомендация для очень простого решения состоит в том, чтобы основывать цвет на текущем номере линии tty. Например, обработайте выходные данные ttyкоманды, чтобы взять только число и извлечь из него цвет. Определенный номер строки tty дается только одному терминалу за раз, вам необходимо сначала закрыть этот терминал, прежде чем ядро ​​выдаст тот же номер строки. Это, в сочетании с 256 цветами, автоматически гарантирует, что вы не увидите один и тот же цвет дважды в определенный момент времени (и даже при 16 цветах это даст довольно равномерное распределение). Нет необходимости в ведении глобального счетчика, и нет необходимости в подсчете терминалов или процессов.

Эгмонт
источник
1
Прекрасная идея с tty. Я думаю, что мы / другие слишком сконцентрировались на этом "вопросе" и забыли, что могут быть другие решения для всей "потребности" :) Я бы даже поиграл с реализацией случайного селектора цвета. Если это 256 цветов, выбор одинаковых / похожих цветов не должен произойти много. Однако ручная настройка цветов для заданных номеров очков даст лучшую персонализацию.
GreggD
@TedM. Да, вопрос был в значительной степени сформулирован как вопрос XY, а именно: «Я хочу, чтобы в каждом терминале был другой цвет, поэтому скажите мне: как мне подсчитать количество терминалов?»
egmont
@TedM. Случайный тоже хорошая идея! (Одно из свойств детерминированного отображения состоит в том, что после sudoing новый пользователь может легко установить тот же цвет приглашения. Это может или не может быть тем, что хочет иметь
исходный спрашивающий
1
Рандомайзер довольно прост: color="\e[38;5;"$(((RANDOM % 231 )+1))"m"(только 231, чтобы отклонить оттенки серого), однако многие из этих цветов оказались просто разными оттенками, и некоторые из них темные, поэтому могут быть почти невидимыми, и я думаю, никто не будет использовать это в реальной жизни ...
GreggD
Мы не знаем версию Ubuntu от Asker. В 16.04 определенно больше нет gnome-pty-helper ( git.gnome.org/browse/vte/commit/?id=299c700 ). Я не собираюсь понижать версию, чтобы проверить точную иерархию процессов в старых версиях. Я знаю, что раньше был такой процесс, но я не совсем уверен, как выглядит иерархия родитель-потомок. Кстати, я взял идею подсчета дочерних процессов из вашего первоначального ответа, поэтому я не понимаю, что «(также вами)», неважно.
egmont
5

В случае одного пользователя, если мы возьмем пример xterm, мы можем просто посчитать количество пид 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, но у процесса (очевидно) нет окна или вкладки. На Мате , процесс все равно существует.

Короче говоря

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

  • Посмотрим, запустим ли мы терминальное приложение, в котором несколько пидов или один пид на одном $DISPLAY(x-session)
  • Из запущенных процессов, отделяю только соответствующие пиды, работающие на этом$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>
Якоб Влейм
источник
Прямо здесь у меня всегда один gnome-pty-helperработает, даже когда вошел только один пользователь (сразу после перезагрузки) и когда я открываю любое количество терминалов, он запускается вторым, тот же помощник. Ваш новый скрипт, кажется, работает для mate-терминала (не смог вызвать ноль), но с xterm, когда у меня открыт только 1, он показывает 0и начинает показывать хорошее число только после второго и с gnome-терминал он всегда показывает слишком мало (вывод, 0когда открыт только один).
GreggD
@TedM. Спасибо, это полезная информация, исправлена ​​сейчас.
Джейкоб Влейм
Я действительно восхищаюсь вашей "страстью" :) ... но все еще проблема с gnome-Terminal. Один дает 1, два дает 1, три дает 2, четыре дает 3 и т. Д. Плюс мое новое открытие, «Тильда» MATE (этот дополнительный «неизвестный» терминал в моем ответе) также имеет ту же проблему, что и gnome-терминал, но с его вкладками. Хотя xterm и mate-терминал работают нормально.
GreggD
@TedM. Спасибо за упоминание! Глупый вопрос, но вы уверены, что используете последний код? На Mate 15.10 все тестовые работы я выполняю без исключения. Какая у тебя версия Mate? На 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
Этот работает очень хорошо для моего помощника терминала и Xterm, кажется пуленепробиваемым.
GreggD
Кратко: who | awk 'END{print NR - 1}'так как вы хотите, чтобы количество строк - 1.
Муру
0

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

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

NonStandardModel
источник
Так как OP хочет использовать результат для автоматической установки цвета терминала, это, кажется, не очень актуальная опция.
Джейкоб Влейм
Извините, теперь я вижу, что он хочет использовать это в сценарии. Но тогда бы ps -ef | grep UserName | grep bash | grep -v grep | wc -l не работает?
NonStandardModel