Come rilevare il numero di terminali aperti da parte dell'utente


9

Sto usando Ubuntu e posso cambiare manualmente il bashcolore del prompt della shell in verde usando

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

Tuttavia, desidero che il colore del prompt della shell cambi automaticamente ogni volta che apro un nuovo terminale o una nuova scheda. Sono consapevole che il TERM tty di base ha 16 colori ed è possibile ruotare i colori se sono aperti più di 16 terminali. La soluzione funzionerà anche quando mi collegherò Putty, tmuxo screen.

La mia idea è quella di scrivere uno script shell e posizionarlo in .bashrccui rileva la nuova sessione terminale che l'utente ha aperto e incrementare un contatore globale da \e[0;31m[a \e[0;47m[. Come rilevare il numero di terminali aperti da parte dell'utente?

Risposte:


8

Se hai davvero bisogno di ottenere il numero di terminali che hai aperto, vai a contare i file di tua proprietà /dev/pts(anche se questo potrebbe includere quelli aperti da processi in background, non da emulatori di terminali grafici). In alternativa, conta il numero di processi figlio dei tuoi emulatori terminali, come mostrato da Jacob nella prima riga della sua risposta.

Evita di fare affidamento whosull'output e di cercare gnome-pty-helperprocessi, poiché questi non funzionano nelle gnome-terminalversioni più recenti.

Si noti che oggigiorno quasi tutti gli emulatori di terminali grafici (incluso lo stucco) e i multiplexer (schermo, tmux) supportano 256 colori. È possibile ottenere prompt colorati davvero belli se si utilizza questa tavolozza.

La mia raccomandazione per una soluzione molto semplice è quella di basare il colore sul numero della linea tty corrente. Ad esempio, elaborare l'output del ttycomando per prendere solo il numero e derivarne il colore. Un certo numero di riga tty è dato a un solo terminale alla volta, dovresti chiudere quel terminale prima che lo stesso numero di riga venga ristampato dal kernel. Questo, combinato con 256 colori, garantisce automaticamente che non vedrai lo stesso colore due volte in un dato momento (e anche con 16 colori darebbe una distribuzione abbastanza uniforme). Non è necessario mantenere un contatore globale e non è necessario contare terminali o processi.


1
Bella idea con tty. Immagino che noi / altri ci siamo concentrati troppo su quella "domanda" e abbiamo dimenticato che potrebbero esserci altre soluzioni per l'intera "necessità" :) Giocherei persino con l'implementazione del selettore di colori casuale. Se ha 256 colori, la selezione di colori uguali / simili non dovrebbe succedere molto. Tuttavia, l'impostazione manuale dei colori per determinati numeri di punti consentirà una migliore personalizzazione.
GreggD,

@TedM. Sì, la domanda era praticamente formulata come una domanda XY, sulla falsariga di: "Vorrei avere un colore diverso in ciascun terminale, quindi dimmi: come conto il numero di terminali?"
egmont,

@TedM. Anche Casuale è una bella idea! (Una proprietà di una mappatura deterministica è che dopo aver annullato l'operazione, il nuovo utente potrebbe facilmente impostare lo stesso colore di richiesta. Questo può o meno ciò che il richiedente originale vuole avere.)
egmont,

1
Il randomizzatore è abbastanza semplice: color="\e[38;5;"$(((RANDOM % 231 )+1))"m"(solo 231 per rifiutare la scala di grigi), tuttavia molti di quei colori erano solo diverse tonalità e un paio di quelli sono scuri, quindi potrebbe essere quasi invisibile e io nessuno lo userà nella vita reale ...
GreggD

Non conosciamo la versione Ubuntu del richiedente. Nel 16.04 non c'è assolutamente più alcun supporto per gnome-pty ( git.gnome.org/browse/vte/commit/?id=299c700 ). Non eseguirò il downgrade per verificare l'esatta gerarchia dei processi nelle versioni precedenti. So che esisteva un tale processo, non sono del tutto sicuro di come fosse la gerarchia genitore-figlio. A proposito, ho preso l'idea del conteggio dei processi figlio dalla tua risposta originale, quindi non capisco che "(anche da te)", non importa.
egmont,

5

In una singola situazione utente, se prendiamo l'esempio di xterm, possiamo semplicemente contare il numero di pid di xterm; xtermcrea un pid separato per ogni finestra.
gnome-terminalesegue comunque un singolo pid, ma la buona notizia è che crea un processo figlio per ogni finestra e / o scheda. possiamo recuperare questi processi figlio con il comando:

pgrep -P <pid_of_gnome-terminal>

Vi sono tuttavia alcune complicazioni da affrontare:

  • Leggendo la tua domanda, possiamo presumere che l' utente in questo caso sia effettivamente proprietario della x-session . Di solito possiamo semplicemente usare $USER-variable, ma questo potrebbe non corrispondere all'utente attualmente connesso $DISPLAY.

  • In una situazione multiutente, i pid appartenenti all'applicazione (o quale) dell'applicazione terminale, non appartengono necessariamente alla corrente $DISPLAY. Dobbiamo dividere solo le offerte e le offerte figlio pertinenti.

  • Su Unity (15.10 o precedente), se un secondo utente accede, viene avviato un processo aggiuntivo ( gnome-pty-helper), che appare come un processo figlio in gnome-terminal, ma il processo (ovviamente) non ha finestre o schede. Su Mate , il processo esiste comunque.

In breve

Per contare il numero di schede e / o finestre di un'applicazione terminale, dobbiamo:

  • Vedi se eseguiamo un'applicazione terminale che ha più pid o un singolo pid su uno $DISPLAY(x-session)
  • Dai processi in esecuzione, dividere solo i pid rilevanti, in esecuzione su questo$DISPLAY
  • Se l'applicazione esegue processi figlio per il suo pid (per finestre / schede), vedere se gnome-pty-helperviene eseguita, per correggere il numero.

Questo può comunque essere ben scritto, per trovare in modo affidabile il numero di finestre e / o schede attualmente aperte.

Il copione

Nello script seguente, l'applicazione terminale di destinazione viene utilizzata come argomento . Lo script funziona su molti terminali su cui l'ho provato. Un'eccezione è Tildain questo momento.

Un esempio

  • Ho effettuato l'accesso con due utenti, uno (non quello corrente) con due gnome-terminalfinestre, uno (quello nell'immagine) con tre gnome-terminalfinestre e due xtermfinestre.

inserisci qui la descrizione dell'immagine

Il comando:

/path/to/get_terms.sh gnome-terminal

uscite:

3

mentre

/path/to/get_terms.sh xterm

uscite:

2

Il copione

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

Usare

  • Copia lo script in un file vuoto, salvalo come get_terms.sh, rendilo eseguibile ed eseguilo con il comando:

    /path/to/get_terms.sh <terminal_application>

Proprio qui ne ho sempre uno in gnome-pty-helperesecuzione, anche quando c'è un solo utente connesso (subito dopo il riavvio) e quando apro un numero qualsiasi di terminali viene eseguito il secondo, stesso aiutante. Il tuo nuovo script sembra funzionare per mate-terminal (non è stato in grado di causare quella cosa zero), ma con xterm, quando ho solo 1 aperto mostra 0e inizia a mostrare un buon numero solo dopo il secondo e con gnome-terminal mostra sempre uno in meno (output 0quando ne viene aperto solo uno).
GreggD,

@TedM. Grazie, queste sono informazioni utili, risolte ora.
Jacob Vlijm,

Ammiro davvero la tua "passione" :) ... ma c'è ancora un problema con gnome-terminal. Uno dà 1, due dà 1, tre dà 2, quattro dà 3, ecc. Inoltre la mia nuova scoperta, "Tilda" del MATE (quel terminale "sconosciuto" in più nella mia risposta) hanno anche lo stesso problema di gnome-terminal, ma con le sue schede. xterm e mate-terminal sembrano funzionare bene però.
GreggD,

@TedM. Grazie per averlo menzionato! Domanda sciocca, ma sei sicuro di usare l'ultimo codice? Su Mate 15.10 tutto il test che eseguo funziona senza eccezioni. Qual è la tua versione Mate? Su Unity tutto ha già funzionato bene.
Jacob Vlijm,

@TedM. Anche sul mio piuttosto vuoto 15.10 Mate, è lì per impostazione predefinita. Ho appena rieseguito i test, perfettamente! potrei chiederti domani o giù di lì per eseguire una versione modificata dello script e pubblicare l'output da qualche parte, per vedere cosa causa l'eccezione nel tuo caso?
Jacob Vlijm,

1

Un awkmodo:

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

Spiegazione:

Nel comando sopra 1 linea, awkviene utilizzato per trovare il conteggio del terminale. All'interno del awkprogramma, sta solo controllando il numero di righe restituite da chi comando - 1.


questo restituisce 0 per me, il che è chiaramente falso ...
Zanna,

Questo funziona molto bene per il mio compagno-terminale e xterm, sembra a prova di proiettile.
GreggD,

In breve: who | awk 'END{print NR - 1}'poiché ciò che vuoi è il numero di righe - 1.
muru,

0

Il modo semplice può essere anche solo quello di eseguire System Monitor(se avviato dal Terminale è necessario scrivere gnome-system-monitor) e nella scheda "Processi" organizzare i processi in esecuzione in base al nome e contare il numero di occorrenze Bashnell'elenco (saranno tutti insieme se si organizza da nome, quindi è facile contare).

Nota che devi cercare Bashe non Gnome Terminalse vuoi vedere il numero di terminali aperti da parte dell'utente. Una volta aperto, un Terminale Gnome Terminalapparirà anche nell'elenco Processi ma rimarrà solo uno anche se vengono aperti più Terminali. Il pulsante "Visualizza" System Monitorconsente di impostare quali processi visualizzare, ad es. Tutti i processi / Processi utente / Attivo ...


Poiché OP vuole utilizzare il risultato per impostare automaticamente i colori dei terminali, questa non sembra un'opzione davvero rilevante.
Jacob Vlijm,

Mi dispiace vedo ora che vuole usarlo nello script. Ma poi sarebbe ps -ef | grep UserName | grep bash | grep -v grep | wc -l non funziona?
Modello non standard
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.