So erkennen Sie die Anzahl der vom Benutzer geöffneten Terminals


9

Ich bin mit Ubuntu und kann manuell ändern bashShell - Prompt Farbe grün mit

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

Ich möchte jedoch, dass sich die Farbe der Shell-Eingabeaufforderung automatisch ändert, wenn ich ein neues Terminal oder eine neue Registerkarte öffne. Mir ist bekannt, dass der Basis-Tty-TERM 16 Farben hat und es in Ordnung ist, die Farben zu drehen, wenn mehr als 16 Terminals geöffnet sind. Funktioniert die Lösung auch, wenn ich eine Verbindung herstelle Putty, tmuxoder screen.

Meine Idee ist es, ein Shell-Skript zu schreiben und es zu platzieren .bashrc, das die neue Terminalsitzung erkennt, die der Benutzer geöffnet hat, und einen globalen Zähler von \e[0;31m[bis zu erhöhen \e[0;47m[. Wie erkennt man die Anzahl der vom Benutzer geöffneten Terminals?

Antworten:


8

Wenn Sie wirklich die Anzahl der geöffneten Terminals ermitteln müssen, zählen Sie die Dateien, deren Eigentümer Sie sind /dev/pts(obwohl dies möglicherweise auch Dateien umfasst, die von Hintergrundprozessen und nicht von grafischen Terminalemulatoren geöffnet wurden). Alternativ können Sie die Anzahl der untergeordneten Prozesse Ihrer Terminalemulatoren zählen, wie von Jacob in der ersten Zeile seiner Antwort gezeigt.

Verlassen Sie sich nicht auf whodie Ausgabe und suchen Sie nach gnome-pty-helperProzessen, da diese in neueren gnome-terminalVersionen nicht funktionieren .

Beachten Sie, dass heutzutage so gut wie alle grafischen Terminalemulatoren (einschließlich Kitt) und Multiplexer (Bildschirm, tmux) 256 Farben unterstützen. Wenn Sie diese Palette verwenden, erhalten Sie wirklich schöne farbige Eingabeaufforderungen.

Meine Empfehlung für eine sehr einfache Lösung ist, die Farbe auf der Nummer der aktuellen tty-Linie zu basieren. Verarbeiten Sie beispielsweise die Ausgabe des ttyBefehls, um nur die Zahl zu übernehmen und daraus die Farbe abzuleiten. Eine bestimmte tty-Zeilennummer wird jeweils nur einem Terminal zugewiesen. Sie müssen dieses Terminal zuerst schließen, bevor der Kernel dieselbe Zeilennummer erneut ausgibt. In Kombination mit 256 Farben wird automatisch garantiert, dass Sie nicht zweimal dieselbe Farbe zu einem bestimmten Zeitpunkt sehen (und selbst bei 16 Farben ergibt sich eine recht gleichmäßige Verteilung). Keine Notwendigkeit, einen globalen Zähler zu verwalten, und keine Notwendigkeit, Terminals oder Prozesse zu zählen.


1
Schöne Idee mit tty. Ich denke, wir / andere haben uns zu sehr auf diese "Frage" konzentriert und vergessen, dass es andere Lösungen für das gesamte "Bedürfnis" geben könnte :) Ich würde sogar mit der Implementierung einer zufälligen Farbauswahl spielen. Wenn es 256 Farben sind, sollte die Auswahl derselben / ähnlicher Farben nicht viel passieren. Das manuelle Einstellen der Farben für bestimmte Punktnummern führt jedoch zu einer besseren Personalisierung.
GreggD

@ TedM. Ja, die Frage wurde so ziemlich als XY-Frage formuliert: "Ich möchte in jedem Terminal eine andere Farbe haben. Sagen Sie mir also: Wie zähle ich die Anzahl der Terminals?"
Egmont

@ TedM. Zufällig ist auch eine schöne Idee! (Eine Eigenschaft einer deterministischen Zuordnung ist, dass der neue Benutzer nach dem Sudoing leicht die gleiche Eingabeaufforderungsfarbe einstellen kann. Dies kann oder kann nicht das sein, was der ursprüngliche Fragesteller haben möchte.)
egmont

1
Randomizer ist ganz einfach: color="\e[38;5;"$(((RANDOM % 231 )+1))"m"(nur 231, um Graustufen abzulehnen), aber viele dieser Farben waren zufällig nur verschiedene Farbtöne und einige davon sind dunkel, so dass sie möglicherweise fast unsichtbar sind, und ich glaube, niemand wird das im wirklichen Leben verwenden ...
GreggD

Wir kennen die Ubuntu-Version des Fragestellers nicht. In 16.04 gibt es definitiv keinen Gnome-Pty-Helfer mehr ( git.gnome.org/browse/vte/commit/?id=299c700 ). Ich werde kein Downgrade durchführen, um die genaue Prozesshierarchie in älteren Versionen zu überprüfen. Ich weiß, dass es früher einen solchen Prozess gab. Ich bin mir nur nicht ganz sicher, wie die Eltern-Kind-Hierarchie aussah. Übrigens habe ich die Idee der Kinderprozesszählung aus Ihrer ursprünglichen Antwort übernommen, daher verstehe ich das "(auch von Ihnen)" nicht, egal.
Egmont

5

In einer Einzelbenutzersituation können wir am Beispiel xtermeinfach die Anzahl der Pids von zählen xterm; xtermErstellt für jedes Fenster eine eigene PID.
gnome-terminalEs wird jedoch eine einzelne PID ausgeführt. Die gute Nachricht ist jedoch, dass für jedes Fenster und / oder jede Registerkarte ein untergeordneter Prozess erstellt wird. Wir können diese untergeordneten Prozesse mit dem folgenden Befehl abrufen:

pgrep -P <pid_of_gnome-terminal>

Es gibt jedoch einige Komplikationen:

  • Wenn Sie Ihre Frage lesen, können wir davon ausgehen, dass der Benutzer in diesem Fall tatsächlich Eigentümer der x-Sitzung ist . Normalerweise können wir einfach die $USER-variable verwenden, aber dies stimmt möglicherweise nicht mit dem aktuell angemeldeten Benutzer von überein $DISPLAY.

  • In einer Mehrbenutzersituation gehören Pids, die zur (entweder welche) Terminalanwendung gehören, nicht unbedingt zum aktuellen $DISPLAY. Wir müssen nur die relevanten Pids und Child-Pids aufteilen.

  • Wenn sich in Unity (15.10 oder niedriger) ein zweiter Benutzer anmeldet, wird ein zusätzlicher Prozess gestartet ( gnome-pty-helper), der als untergeordneter Prozess angezeigt wird gnome-terminal, aber der Prozess hat (offensichtlich) kein Fenster oder keine Registerkarte. Auf Mate existiert der Prozess trotzdem.

Zusamenfassend

Um die Anzahl der Registerkarten und / oder Fenster einer Terminalanwendung zu zählen, müssen wir:

  • Überprüfen Sie, ob wir eine Terminalanwendung ausführen, die mehrere Pids oder eine einzelne PID auf einer hat $DISPLAY(x-Sitzung).
  • Teilen Sie von den laufenden Prozessen nur die relevanten Pids ab, die auf diesem ausgeführt werden$DISPLAY
  • Wenn die Anwendung untergeordnete Prozesse für ihre PID ausführt (für Fenster / Registerkarten), überprüfen Sie, ob sie ausgeführt gnome-pty-helperwird, um die Nummer zu korrigieren.

Dies kann jedoch sehr gut per Skript ausgeführt werden, um die Anzahl der aktuell geöffneten Fenster und / oder Registerkarten zuverlässig zu ermitteln.

Das Skript

Im folgenden Skript wird die Zielterminalanwendung als Argument verwendet . Das Skript funktioniert auf vielen Terminals, auf denen ich es getestet habe. Eine Ausnahme ist Tildain diesem Moment.

Ein Beispiel

  • Ich habe zwei Benutzer angemeldet, einen (nicht den aktuellen) mit zwei gnome-terminalFenstern, einen (den im Bild) mit drei gnome-terminalFenstern und zwei xtermFenster.

Geben Sie hier die Bildbeschreibung ein

Der Befehl:

/path/to/get_terms.sh gnome-terminal

Ausgänge:

3

während

/path/to/get_terms.sh xterm

Ausgänge:

2

Das Skript

#!/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

Benutzen

  • Kopieren Sie das Skript in eine leere Datei, speichern Sie es unter get_terms.sh, machen Sie es ausführbar und führen Sie es mit dem folgenden Befehl aus:

    /path/to/get_terms.sh <terminal_application>

Genau hier gnome-pty-helperläuft immer eines , auch wenn nur ein Benutzer angemeldet ist (direkt nach dem Neustart) und wenn ich eine beliebige Anzahl von Terminals öffne, läuft es als zweiter, derselbe Helfer. Ihr neues Skript scheint für Mate-Terminal zu funktionieren (konnte dieses Null-Ding nicht verursachen), aber mit xterm wird, wenn ich nur 1 geöffnet habe, 0erst nach dem zweiten und mit gnome-terminal eine gute Nummer angezeigt es wird immer eins zu weniger angezeigt (Ausgabe, 0wenn nur eines geöffnet ist).
GreggD

@ TedM. Danke, das sind nützliche Informationen, die jetzt behoben wurden.
Jacob Vlijm

Ich bewundere deine "Leidenschaft" wirklich :) ... aber es gibt immer noch ein Problem mit dem Gnome-Terminal. Eins gibt 1, zwei gibt 1, drei gibt 2, vier gibt 3 usw. Und meine neue Entdeckung, MATEs "Tilda" (das eine zusätzliche "unbekannte" Terminal in meiner Antwort), hat ebenfalls das gleiche Problem wie das Gnome-Terminal, aber mit seinen Registerkarten. xterm und mate-terminal scheinen aber gut zu funktionieren.
GreggD

@ TedM. Danke fürs Erwähnen! Dumme Frage, aber sind Sie sicher, dass Sie den neuesten Code verwenden? Auf Mate 15.10 führen alle Tests ausnahmslos Arbeit aus. Was ist deine Mate-Version? Auf Unity hat schon alles gut funktioniert.
Jacob Vlijm

@ TedM. Auch auf meinem ziemlich leeren 15.10 Mate ist es standardmäßig da. Wiederholen Sie einfach die Tests, perfekt! Könnte ich Sie morgen oder so bitten, eine bearbeitete Version des Skripts auszuführen und die Ausgabe irgendwo zu veröffentlichen, um zu sehen, was die Ausnahme in Ihrem Fall verursacht?
Jacob Vlijm

1

Ein awkWeg:

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

Erläuterung:

Im obigen 1-Liner-Befehl awkwird der Zählerstand des Terminals ermittelt. Innerhalb des awkProgramms wird lediglich die Anzahl der von who zurückgegebenen Zeilen überprüft - 1.


das gibt 0 für mich zurück, was eindeutig falsch ist ...
Zanna

Dieser funktioniert sehr gut für mein Mate-Terminal & xterm, scheint kugelsicher.
GreggD

Kurz gesagt: who | awk 'END{print NR - 1}'Da Sie möchten, ist die Anzahl der Zeilen - 1.
22.

0

Ein einfacher Weg kann auch darin bestehen, nur auszuführen System Monitor(wenn Sie vom Terminal aus starten , müssen Sie schreiben gnome-system-monitor) und auf der Registerkarte "Prozesse" die laufenden Prozesse nach Namen zu ordnen und dann die Anzahl der Vorkommen Bashin der Liste zu zählen (sie werden alle zusammen sein, wenn Sie nach arrangieren Name, so ist es einfach zu zählen).

Beachten Sie, dass Sie suchen müssen Bashund nicht, Gnome Terminalwenn Sie die Anzahl der geöffneten Terminals nach Benutzer anzeigen möchten. Sobald Sie ein Terminal öffnen, Gnome Terminalwird es auch in der Prozessliste angezeigt, bleibt jedoch auch dann eines, wenn mehrere Terminals geöffnet werden. Mit der Schaltfläche "Anzeigen" in System Monitorkönnen Sie festlegen, welche Prozesse angezeigt werden sollen, z. Alle Prozesse / Benutzerprozesse / Aktiv ...


Da OP das Ergebnis verwenden möchte, um die Terminalfarbe (n) automatisch einzustellen, scheint dies keine wirklich relevante Option zu sein.
Jacob Vlijm

Entschuldigung, ich sehe jetzt, dass er es im Skript verwenden möchte. Aber dann würde ps -ef | grep Benutzername | grep bash | grep -v grep | wc -l funktioniert nicht?
NonStandardModel
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.