Como detectar o número de terminais abertos pelo usuário

8

Estou usando o Ubuntu e posso alterar manualmente a cor do prompt bash para verde usando

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

No entanto, desejo que a cor do prompt do shell seja alterada automaticamente sempre que eu abrir um novo terminal ou guia. Estou ciente de que o termo básico tty tem 16 cores, e não há problema em girar as cores se mais de 16 terminais estiverem abertos. A solução também funcionará quando eu me conectar através de Putty , tmux ou screen .

Minha ideia é escrever um script de shell e colocá-lo em .bashrc , que detecta a nova sessão de terminal que o usuário abriu e incrementa um contador global de \e[0;31m[ para \e[0;47m[ . Como detectar o número de terminais abertos pelo usuário?

    
por manav m-n 20.05.2016 / 07:57

4 respostas

7

Se você realmente precisa obter o número de terminais que você abriu, vá para contar os arquivos que pertencem a você em /dev/pts (embora isso possa incluir os abertos por processos em segundo plano, não por emuladores de terminal gráficos). Como alternativa, conte o número de processos filhos do (s) emulador (es) de terminal, conforme mostrado por Jacob na primeira linha de sua resposta.

Evite confiar na saída de who e procure por gnome-pty-helper processos, pois eles não funcionam em versões mais recentes de gnome-terminal .

Note que hoje em dia praticamente todos os emuladores de terminais gráficos (incluindo massa) e multiplexadores (tela, tmux) suportam 256 cores. Você pode obter prompts coloridos muito legais se usar essa paleta.

Minha recomendação para uma solução muito simples é basear a cor no número atual da linha tty. Por exemplo. processa a saída do comando tty para obter apenas o número e derivar a cor disso. Um determinado número de linha tty é dado apenas a um terminal de cada vez, você teria que fechar esse terminal antes que o mesmo número de linha fosse reeditado pelo kernel. Isso, combinado com 256 cores, garante automaticamente que você não verá a mesma cor duas vezes em um determinado momento (e, mesmo com 16 cores, fornecerá uma distribuição bastante uniforme). Não há necessidade de manter um contador global e não há necessidade de contar terminais ou processos.

    
por egmont 20.05.2016 / 21:33
5

Em uma situação de usuário único, se tomarmos o exemplo de xterm , podemos simplesmente contar o número de pids de xterm ; xterm cria um pid separado para cada janela.
gnome-terminal no entanto executa um único pid, mas a boa notícia é que ele cria um processo filho para cada janela e / ou guia. podemos recuperar esses processos filhos pelo comando:

pgrep -P <pid_of_gnome-terminal>

Existem no entanto algumas complicações para lidar com:

  • Lendo sua pergunta, podemos supor que usuário neste caso é realmente proprietário da sessão x . Normalmente, podemos simplesmente usar o $USER -variable, mas isso pode não corresponder ao usuário atualmente conectado de $DISPLAY .

  • Em uma situação multiusuário, os pids pertencentes ao (qual) aplicativo de terminal não pertencem necessariamente ao atual $DISPLAY . Precisamos dividir apenas os pids e child-pids relevantes.

  • No Unity (15.10 ou inferior), se um segundo usuário efetuar login, será iniciado um processo adicional ( gnome-pty-helper ), que aparece como um processo filho em gnome-terminal , mas o processo (obviamente) tem sem janela ou aba. Em Mate , o processo existe mesmo assim.

Em suma

Para contar o número de guias e / ou janelas de um aplicativo de terminal, precisamos:

  • Veja se executamos um aplicativo de terminal que possui vários pids ou um único pid em um $DISPLAY (x-session)
  • A partir dos processos em execução, divida somente os pids relevantes, em execução neste $DISPLAY
  • Se o aplicativo executar processos-filhos para seu pid (para janelas / guias), veja se gnome-pty-helper é executado para corrigir o número.

Isso pode muito bem ser roteirizado, no entanto, para encontrar com segurança o número de janelas e / ou abas atualmente abertas.

O script

No script abaixo, o aplicativo terminal direcionado é usado como um argumento . O script funciona em muitos terminais nos quais testei. Uma exceção é Tilda neste momento.

Um exemplo

  • Eu tenho dois usuários conectados, um (não o atual) com duas gnome-terminal windows, um (o da imagem) com três gnome-terminal windows e dois xterm windows.

O comando:

/path/to/get_terms.sh gnome-terminal

saídas:

3

enquanto

/path/to/get_terms.sh xterm

saídas:

2

O script

#!/bin/bash

terminal=

# get the user running the current x-session
username=$(who | grep $DISPLAY | head -1 | awk '{print }')
# 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

Para usar

  • Copie o script em um arquivo vazio, salve-o como get_terms.sh , torne-o executável e execute-o pelo comando:

    /path/to/get_terms.sh <terminal_application>
    
por Jacob Vlijm 20.05.2016 / 08:20
1

Uma awk way:

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

Explicação:

No comando acima de 1 liner, awk é usado para encontrar a contagem do terminal. Dentro do programa awk , está apenas verificando o número de linhas retornadas por quem comanda - 1.

    
por snoop 20.05.2016 / 08:25
0

O caminho simples também pode ser apenas para executar System Monitor (se iniciado no Terminal você deve escrever gnome-system-monitor ) e na guia "Processos" organizar os processos em execução por Nome e contar o número de ocorrências de Bash em a listagem (eles estarão todos juntos se você organizar por nome, então é fácil contar).

Observe que você deve procurar Bash e não Gnome Terminal se quiser ver o número de terminais abertos pelo usuário. Depois de abrir um Terminal Gnome Terminal também aparecerá na lista Processos, mas permanecerá apenas um, mesmo se mais Terminais forem abertos. O botão "Visualizar" em System Monitor permite que você defina quais processos ver, por exemplo. Todos os Processos / Processos do Usuário / Ativo ...

    
por NonStandardModel 27.05.2016 / 23:04