사용자가 열린 터미널 수를 감지하는 방법


9

우분투를 사용하고 수동으로 변경할 수 있습니다 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(그래픽 터미널 에뮬레이터가 아닌 백그라운드 프로세스에 의해 열린 파일 이 포함될 수 있음). 또는 Jacob의 응답 첫 줄에 표시된대로 터미널 에뮬레이터의 하위 프로세스 수를 계산하십시오.

최신 버전에서는 작동하지 않으므로 who의 결과 에 의존하고 gnome-pty-helper프로세스를 찾지 마십시오 gnome-terminal.

오늘날 거의 모든 그래픽 터미널 에뮬레이터 (퍼티 포함) 및 멀티플렉서 (스크린, tmux)는 256 색을 지원합니다. 이 팔레트를 사용하면 멋진 색상의 프롬프트를 얻을 수 있습니다.

매우 간단한 해결책에 대한 권장 사항은 현재 tty 줄의 번호를 기준으로 색상을 지정하는 것입니다. 예를 들어 tty명령 의 출력을 처리하여 숫자 만 가져 와서 그 색상을 얻습니다. 특정 tty 라인 번호는 한 번에 하나의 터미널에만 제공되므로 동일한 라인 번호가 커널에 의해 재발행되기 전에 먼저 해당 터미널을 닫아야합니다. 256 색과 결합하면 주어진 시간에 같은 색이 두 번 표시되지 않으며 (16 색이라도 상당히 균일 한 분포를 제공함) 자동으로 보장합니다. 글로벌 카운터를 유지할 필요가 없으며 터미널이나 프로세스를 계산할 필요가 없습니다.


1
와 아름다운 아이디어 tty. 나는 우리 / 다른 사람들이 그 "질문"에 너무 집중하고 전체 "필요"에 대한 다른 해결책이 있다는 것을 잊어 버린 것 같습니다 :) 심지어 임의의 색상 선택기를 구현하는 것조차 할 것입니다. 256 색인 경우 동일 / 유사한 색상을 선택하면 별다른 문제가 발생하지 않습니다. 그러나 주어진 pts 숫자에 대한 색상을 수동으로 설정하면 더 나은 개인화가 가능합니다.
GreggD

@TedM. 그렇습니다. "각 터미널마다 다른 색을 원합니다. 따라서 터미널 수를 어떻게 계산합니까?"와 같은 질문을 XY 질문으로 표현했습니다.
egmont

@TedM. 랜덤도 좋은 생각입니다! (결정 론적 매핑의 한 가지 속성은 새로운 사용자가 sudo 후 쉽게 같은 프롬프트 색상을 설정할 수 있다는 것입니다. 이것은 원래의
asker가 원했던

1
랜덤은 매우 쉽습니다 : color="\e[38;5;"$(((RANDOM % 231 )+1))"m"(전용 231 그레이 스케일을 거부하기 위해), 그 색상 그러나 많은 사람들이 그렇게 거의 보이지 수 있습니다 어두운 내가 ... 아무도 실생활에서 그것을 사용하지 않습니다 guees 단지 다른 색조 그 중 몇 우연히
GreggD

우리는 asker의 Ubuntu 버전을 모른다. 16.04에는 더 이상 gnome-pty-helper가 없습니다 ( git.gnome.org/browse/vte/commit/?id=299c700 ). 이전 버전에서 정확한 프로세스 계층 구조를 확인하기 위해 다운 그레이드하지 않을 것입니다. 나는 그런 과정이 있었음을 알고 있지만 부모-자식 계층이 어떻게 생겼는지 완전히 확신하지 못합니다. 그건 그렇고, 나는 당신의 원래 반응에서 자녀 프로세스 수 아이디어를 취 했으므로 "(또한 당신에 의해)"라는 것을 이해하지 못합니다.
egmont

5

단일 사용자 상황에서의 예 xterm를 살펴보면 pid 수를 계산할 수 있습니다 xterm. xterm각 창마다 별도의 pid를 만듭니다.
gnome-terminal그러나 하나의 pid를 실행하지만 좋은 소식은 각 창 및 / 또는 탭마다 자식 프로세스를 만드는 것입니다. 다음과 같은 명령으로 이러한 하위 프로세스를 검색 할 수 있습니다.

pgrep -P <pid_of_gnome-terminal>

그러나 다루어야 할 몇 가지 합병증이 있습니다.

  • 귀하의 질문을 읽으면 이 경우 사용자 는 실제로 x-session의 소유자 라고 가정 할 수 있습니다 . 일반적으로 단순히 $USER-variable을 사용할 수 있지만 현재 로그인 한 사용자와 일치하지 않을 수 있습니다 $DISPLAY.

  • 다중 사용자 상황에서 (어떤) 터미널 응용 프로그램에 속하는 pid는 반드시 current에 속할 필요는 없습니다 $DISPLAY. 관련 pid와 자식 pid 만 분리해야합니다.

  • Unity (15.10 이하)에서 두 번째 사용자가 로그인하면 추가 프로세스가 시작 ( gnome-pty-helper)되며에 하위 프로세스로 표시 gnome-terminal되지만 프로세스에는 창 또는 탭이 없습니다. 에 메이트 , 과정은 어쨌든 존재한다.

한마디로

터미널 애플리케이션의 탭 및 / 또는 창 수를 세려면 다음을 수행해야합니다.

  • 하나의 x 에 여러 개의 pid 또는 하나의 pid 가있는 터미널 응용 프로그램을 실행하는지 확인하십시오$DISPLAY
  • 실행중인 프로세스 에서 관련 pid 분리 하십시오.$DISPLAY
  • 응용 프로그램이 pid에 대한 자식 프로세스를 실행하는 경우 (Windows / 탭의 경우) 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로그인 한 사용자가 한 명 뿐인 경우 (재부팅 직후), 터미널을 얼마든지 열면 동일한 도우미로 두 번째로 실행됩니다. 새 스크립트가 메이트 터미널에서 작동하는 것 같습니다 (제로를 유발할 수 없었습니다). xterm을 사용하면 1 개만 열면 0두 번째 스크립트 와 그놈 터미널로만 좋은 숫자가 표시되고 시작됩니다. 항상 하나를 너무 적게 표시합니다 ( 0하나만 열면 출력 ).
GreggD

@TedM. 감사합니다. 유용한 정보로 수정되었습니다.
Jacob Vlijm

나는 당신의 "열정"을 정말로 존경합니다 :) ...하지만 그놈 터미널에는 여전히 문제가 있습니다. 하나는 1, 2는 1, 3, 2, 4, 3 등을 준다. 나의 새로운 발견과 더불어, MATE의 "틸다 (Tilda)"(내 대답에서 하나의 "알 수없는"터미널)도 그놈 터미널과 같은 문제가있다. 탭이 있습니다. xterm과 mate-terminal은 잘 작동하는 것 같습니다.
GreggD

@TedM. 언급 해 주셔서 감사합니다! 바보 같은 질문이지만 최신 코드를 사용 하시겠습니까? Mate 15.10에서 모든 테스트는 예외없이 작동합니다. 메이트 버전은 무엇입니까? 유니티에서는 모든 것이 이미 잘 작동했습니다.
Jacob Vlijm

@TedM. 또한 내 빈 15.10 메이트에는 기본적으로 있습니다. 테스트를 완벽하게 재실행하십시오! 내일 쯤에 편집 된 스크립트 버전을 실행하고 어딘가에 출력을 게시하여 귀하의 경우 예외의 원인을 알 수 있습니까?
Jacob Vlijm

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 이기 때문입니다.
muru

0

간단한 방법은 실행하는 것입니다 System Monitor(터미널에서 시작한 경우 쓰기해야 함 gnome-system-monitor). "프로세스"탭 아래에서 이름으로 실행중인 프로세스를 정렬 Bash하고 목록에서 발생 횟수를 세는 것보다 (모두 정렬하면 모두 함께됩니다 이름, 그래서 계산하기 쉽습니다).

사용자가 열린 터미널 수를 보려면 찾아서는 Bash안됩니다 Gnome Terminal. 터미널을 열면 Gnome Terminal프로세스 목록에도 터미널 이 나타나지만 더 많은 터미널이 열려 있어도 하나만 유지됩니다. 예를 들어 "보기"버튼을 System Monitor사용하면 볼 프로세스를 설정할 수 있습니다. 모든 프로세스 / 사용자 프로세스 / 활성 ...


OP는 결과를 사용하여 터미널 색상을 자동으로 설정하려고하므로 실제로 관련이없는 옵션으로 보입니다.
Jacob Vlijm

죄송합니다. 이제 스크립트에서 사용하고 싶습니다. 그러나 ps -ef | grep 사용자 이름 | grep bash | grep -v grep | 화장실 -l 작동하지 않습니까?
NonStandardModel
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.