Як визначити кількість відкритих користувачем терміналів


9

Я використовую Ubuntu і можу вручну змінити bashколір підказки оболонки на зелений за допомогою

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

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

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

Відповіді:


8

Якщо вам дійсно потрібно отримати кількість відкритого терміналу, займіться підрахунком файлів, якими ви належите /dev/pts(хоча це може включати файли , відкриті фоновими процесами, а не графічними емуляторами терміналів). Крім того, підрахуйте кількість дочірніх процесів емулятора терміналів, як показано Якобом у першому рядку його відповіді.

Уникайте покладатися на whoвихідний результат та шукати gnome-pty-helperпроцеси, оскільки вони не працюють у нових gnome-terminalверсіях.

Зауважимо, що сьогодні майже всі графічні емулятори терміналів (включаючи шпаклівку) та мультиплексори (екран, tmux) підтримують 256 кольорів. Якщо ви користуєтеся цією палітрою, ви можете отримати дуже гарні кольорові підказки.

Моя рекомендація щодо дуже простого рішення - це базувати колір на поточному номері рядка tty. Наприклад, обробити вихід ttyкоманди, щоб взяти тільки число і отримати колір з цього. Певний номер рядка tty надається лише одному терміналу за раз, вам доведеться спочатку закрити цей термінал, перш ніж той же номер рядка повторно видається ядром. Це в поєднанні з 256 кольорами автоматично гарантує, що ви не побачите один і той же колір двічі (і навіть з 16 кольорами він дасть цілком рівномірний розподіл). Не потрібно підтримувати глобальний лічильник і не потрібно рахувати термінали чи процеси.


1
Красива ідея с tty. Я думаю, що ми / інші занадто багато сконцентрувались на цьому "питанні" і забули, що можуть бути інші рішення для цілої "потреби" :) Я б навіть зіграв з реалізацією випадкового селектора кольорів. Якщо це 256 кольорів, вибір однакових / подібних кольорів не повинен відбуватися багато. Однак налаштування кольорів вручну для заданих номерів очок дасть кращу персоналізацію.
GreggD

@TedM. Так, це питання в значній мірі було викладено як питання XY, так: "Я хочу мати різний колір у кожному терміналі, тому скажіть мені: як я рахую кількість терміналів?"
Егмонт

@TedM. Випадкові - теж приємна ідея! (Однією з властивостей детермінованого відображення є те, що після набору доступу новий користувач може легко встановити той самий колір підказки. Це може бути, а може і не бути тим, що хоче мати
початковий запитувач

1
Randomizer досить простий: color="\e[38;5;"$(((RANDOM % 231 )+1))"m"(лише 231 відхилити відтінки сірого), проте багато хто з цих кольорів були просто різними відтінками, а пара таких темних, тому вони можуть бути майже непомітними, і я не використовую, що ніхто не використовує це в реальному житті ...
GreggD

Ми не знаємо версію Ubuntu особи, що претендувала. У 16.04 напевно вже немає гнома-pty-helper ( git.gnome.org/browse/vte/commit/?id=299c700 ). Я не збираюся знижувати версію, щоб перевірити точну ієрархію процесів у старих версіях. Я знаю, що раніше був такий процес, я просто не зовсім впевнений, як виглядала ієрархія батько-дитина. До речі, я взяв ідею підрахунку дочірнього процесу з вашої оригінальної відповіді, так що я не розумію, що "(також від вас)", неважливо.
Егмонт

5

У єдиній ситуації з користувачем, якщо ми беремо приклад xterm, ми можемо просто підрахувати кількість підписів xterm; xtermстворює окремий під для кожного вікна.
gnome-terminalоднак запускає один під, але гарна новина полягає в тому, що він створює дочірній процес для кожного вікна та / або вкладки. ми можемо отримати ці дочірні процеси за допомогою команди:

pgrep -P <pid_of_gnome-terminal>

Однак є кілька ускладнень, які можна вирішити:

  • Читаючи ваше запитання, ми можемо припустити, що користувач у цьому випадку насправді є власником x-сеансу . Зазвичай ми можемо просто використовувати $USER-variable, але це може не відповідати поточно зареєстрованому користувачеві $DISPLAY.

  • У багатокористувацькій ситуації підси, що належать до (або якої) термінальної програми, не обов'язково належать до поточного $DISPLAY. Нам потрібно розділити лише відповідні піди та підручники.

  • У Unity (15.10 або новішої версії), якщо другий користувач входить у систему, запускається додатковий процес ( gnome-pty-helper), який відображається як дочірній процес gnome-terminal, але процес (очевидно) не має вікна або вкладки. Що стосується Mate , процес все одно існує.

Коротко

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

  • Подивіться, чи ми запускаємо термінальну програму, яка містить декілька підписів або один під на одному $DISPLAY(x-сесія)
  • Від запущених процесів відокремте лише відповідні піди, які працюють на цьому$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-terminal (не зміг викликати цю нульову річ), але з xterm, коли я відкрив лише 1, він показує 0і починає показувати хороший номер лише після другого та з gnome-terminal він завжди показує один занадто менше (виводиться, 0коли відкривається лише один).
ГреггД

@TedM. Дякую, корисна інформація, виправлена ​​зараз.
Яків Влійм

Я дуже захоплююсь вашою "пристрастю" :) ... але все ж є проблема з gnome-терміналом. Один дає 1, два дає 1, три дає 2, чотири дає 3 і т. Д. Плюс моє нове відкриття, "Tilda" (що є одним додатковим "невідомим" терміналом MATE) також має таке ж питання, як і gnome-термінал, але з його вкладками. Схоже, xterm і mate-terminal, здається, працюють добре.
ГреггД

@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програми це просто перевірка кількості рядків, повернених командою хто - 1.


це для мене повертає 0, що явно не відповідає дійсності ...
Zanna

Ця робота працює дуже добре для мого мате-терміналу та xterm, здається бездоганною.
GreggD

Точно так: who | awk 'END{print NR - 1}'оскільки ви хочете, це кількість рядків - 1.
muru

0

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

Зауважте, що ви повинні шукати, Bashа не робити, Gnome Terminalякщо ви хочете побачити кількість відкритих терміналів користувачем. Щойно ви відкриєте термінал, Gnome Terminalвін також з’явиться у списку процесів, але він залишиться лише одним, навіть якщо відкрито більше терміналів. Кнопка "Перегляд" System Monitorдозволяє встановлювати, які процеси бачити, наприклад. Усі процеси / Користувацькі процеси / Активні ...


Оскільки ОП хоче використовувати результат для автоматичного встановлення кольорів терміналів, це здається не дуже актуальним варіантом.
Яків Влійм

Вибачте, я зараз бачу, що він хоче використовувати це в сценарії. Але тоді би ps -ef | grep UserName | греп баш | grep -v grep | wc-я не працюю?
NonStandardModel
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.