Cách phát hiện số lượng thiết bị đầu cuối đã mở của người dùng


9

Tôi đang sử dụng Ubuntu và có thể tự thay đổi bashmàu dấu nhắc vỏ sang màu xanh bằng cách sử dụng

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

Tuy nhiên, tôi muốn màu dấu nhắc shell tự động thay đổi bất cứ khi nào tôi mở một thiết bị đầu cuối hoặc tab mới. Tôi biết rằng Tty cơ bản có 16 màu và không thể xoay màu nếu có hơn 16 thiết bị đầu cuối được mở. Giải pháp cũng sẽ hoạt động khi tôi kết nối thông qua Putty, tmuxhoặc screen.

Ý tưởng của tôi là viết một kịch bản shell và đặt nó trong .bashrcđó phát hiện phiên cuối mới mà người dùng đã mở và tăng một bộ đếm toàn cầu từ \e[0;31m[đến \e[0;47m[. Làm thế nào để phát hiện số lượng thiết bị đầu cuối mở bởi người dùng?

Câu trả lời:


8

Nếu bạn thực sự cần lấy số lượng thiết bị đầu cuối mà bạn đã mở, hãy đi đếm các tệp do bạn sở hữu bên dưới /dev/pts(mặc dù điều này có thể bao gồm các tệp được mở bởi các quy trình nền, không phải bằng trình giả lập thiết bị đầu cuối đồ họa). Hoặc, đếm số lượng tiến trình con của trình giả lập thiết bị đầu cuối của bạn, như được hiển thị bởi Jacob trong dòng đầu tiên của phản hồi của anh ấy.

Tránh dựa vào whođầu ra và tìm kiếm các gnome-pty-helperquy trình, vì chúng không hoạt động trong các gnome-terminalphiên bản mới hơn .

Lưu ý rằng hiện nay khá nhiều tất cả các trình giả lập thiết bị đầu cuối đồ họa (bao gồm cả putty) và bộ ghép kênh (màn hình, tmux) hỗ trợ 256 màu. Bạn có thể nhận được lời nhắc màu thực sự đẹp nếu bạn sử dụng bảng màu này.

Đề xuất của tôi cho một giải pháp rất đơn giản là dựa trên màu của số tty hiện tại. Ví dụ, xử lý đầu ra của ttylệnh để chỉ lấy số và lấy màu từ đó. Một số dòng tty nhất định chỉ được cấp cho một thiết bị đầu cuối tại một thời điểm, trước tiên bạn phải đóng thiết bị đầu cuối đó trước khi số dòng tương tự được cấp lại bởi hạt nhân. Điều này, kết hợp với 256 màu, tự động đảm bảo rằng bạn sẽ không nhìn thấy cùng một màu hai lần tại một thời điểm nhất định (và thậm chí với 16 màu, nó sẽ phân phối khá đều). Không cần duy trì bộ đếm toàn cầu, và không cần đếm các thiết bị đầu cuối hoặc quy trình.


1
Ý tưởng đẹp với tty. Tôi đoán rằng chúng tôi / những người khác đã tập trung quá nhiều vào "câu hỏi" đó và quên rằng có thể có các giải pháp khác cho toàn bộ "nhu cầu" :) Tôi thậm chí sẽ chơi với việc thực hiện bộ chọn màu ngẫu nhiên. Nếu là 256 màu, việc chọn các màu giống nhau / tương tự sẽ không xảy ra nhiều. Tuy nhiên, cài đặt màu thủ công cho các số pts đã cho sẽ giúp cá nhân hóa tốt hơn.
GreggD

@TedM. Có, câu hỏi được đặt ra khá nhiều như một câu hỏi XY, dọc theo dòng: "Tôi muốn có màu khác nhau trong mỗi thiết bị đầu cuối, vì vậy hãy cho tôi biết: làm thế nào để tôi đếm số lượng thiết bị đầu cuối?"
egmont

@TedM. Ngẫu nhiên cũng là một ý tưởng tốt đẹp! (Một tài sản của một ánh xạ xác định là sau khi sudoing người dùng mới có thể dễ dàng thiết lập màu sắc nhanh chóng cùng này có thể hoặc có thể không phải những gì Người hỏi ban đầu muốn có..)
Egmont

1
Randomizer là khá dễ dàng: color="\e[38;5;"$(((RANDOM % 231 )+1))"m"(chỉ 231 để từ chối greyscale), tuy nhiên rất nhiều những màu sắc đã xảy ra với thể chỉ là sắc thái khác nhau và vài những là tối như vậy có thể được gần như vô hình và tôi guees ai sẽ sử dụng trong cuộc sống thực ...
GreggD

Chúng tôi không biết phiên bản Ubuntu của người hỏi. Trong 16.04 chắc chắn không còn gnome-pty-helper nữa ( git.gnome.org/browse/vte/commit/?id=299c700 ). Tôi sẽ không hạ cấp để kiểm tra phân cấp quy trình chính xác trong các phiên bản cũ hơn. Tôi biết đã từng có quá trình như vậy, tôi chỉ không hoàn toàn chắc chắn hệ thống phân cấp cha-con trông như thế nào. Nhân tiện, tôi đã lấy ý tưởng đếm quá trình trẻ em từ phản hồi ban đầu của bạn, vì vậy tôi không hiểu rằng "(cũng bởi bạn)", không bao giờ.
egmont

5

Trong một tình huống người dùng, nếu chúng ta lấy ví dụ về xterm, chúng ta có thể chỉ cần đếm số lượng pids của xterm; xtermtạo ra một pid riêng cho mỗi và mọi cửa sổ.
gnome-terminaltuy nhiên chạy một pid duy nhất, nhưng tin tốt là nó tạo ra một tiến trình con cho mỗi và mọi cửa sổ và / hoặc tab. chúng ta có thể truy xuất các tiến trình con này bằng lệnh:

pgrep -P <pid_of_gnome-terminal>

Tuy nhiên, có một vài biến chứng để giải quyết:

  • Đọc câu hỏi của bạn, chúng tôi có thể cho rằng người dùng trong trường hợp này thực sự là chủ sở hữu của phiên x . Thông thường chúng ta chỉ có thể sử dụng $USER-variable, nhưng điều này có thể không phù hợp với người dùng hiện đang đăng nhập $DISPLAY.

  • Trong tình huống nhiều người dùng, các pids thuộc về ứng dụng đầu cuối (hoặc là), không nhất thiết phải thuộc về hiện tại $DISPLAY. Chúng ta chỉ cần tách ra các pids và pids trẻ em có liên quan.

  • Trên Unity (15.10 trở xuống), nếu người dùng thứ hai đăng nhập, một quy trình bổ sung được bắt đầu ( gnome-pty-helper), xuất hiện dưới dạng một tiến trình con gnome-terminal, nhưng quá trình (rõ ràng) không có cửa sổ hoặc tab. Trên Mate , quá trình tồn tại dù sao đi nữa.

Nói ngắn gọn

Để đếm số lượng tab và / hoặc cửa sổ của ứng dụng đầu cuối, chúng ta cần:

  • Xem nếu chúng tôi chạy một ứng dụng đầu cuối có nhiều pids hoặc một pid trên một $DISPLAY(phiên x)
  • Từ tiến trình đang chạy, tách ra chỉ là PID có liên quan, chạy về vấn đề này$DISPLAY
  • Nếu ứng dụng chạy các tiến trình con cho pid của nó (đối với windows / tab), hãy xem nếu gnome-pty-helperchạy, để sửa số.

Điều này rất có thể được viết kịch bản, tuy nhiên, đáng tin cậy để tìm số lượng cửa sổ và / hoặc tab hiện đang mở.

Kịch bản

Trong đoạn script bên dưới, ứng dụng đầu cuối được nhắm mục tiêu được sử dụng làm đối số . Kịch bản hoạt động trên nhiều thiết bị đầu cuối mà tôi đã thử nghiệm. Một ngoại lệ là Tildatại thời điểm này.

Một ví dụ

  • Tôi có hai người dùng đăng nhập, một (không phải hiện tại) có hai gnome-terminalcửa sổ, một (một trong hình) với ba gnome-terminalcửa sổ và hai xtermcửa sổ.

nhập mô tả hình ảnh ở đây

Lệnh:

/path/to/get_terms.sh gnome-terminal

đầu ra:

3

trong khi

/path/to/get_terms.sh xterm

đầu ra:

2

Kịch bản

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

Để sử dụng

  • Sao chép tập lệnh vào một tệp trống, lưu nó dưới dạng get_terms.sh, làm cho nó có thể thực thi được và chạy nó bằng lệnh:

    /path/to/get_terms.sh <terminal_application>

Ngay tại đây, tôi luôn có một người gnome-pty-helperđang chạy, ngay cả khi chỉ có một người dùng đăng nhập (ngay sau khi khởi động lại) và khi tôi mở bất kỳ số lượng thiết bị đầu cuối nào, nó sẽ chạy thứ hai, cùng một người trợ giúp. Tập lệnh mới của bạn dường như đang hoạt động cho mate-terminal (không thể tạo ra số 0 đó), nhưng với xterm, khi tôi chỉ mở 1, nó hiển thị 0và bắt đầu hiển thị số tốt chỉ sau lần thứ hai và với thiết bị đầu cuối gnome nó luôn hiển thị quá ít (xuất ra 0khi chỉ mở một).
GreggD

@TedM. Cảm ơn, đó là thông tin hữu ích, cố định ngay bây giờ.
Jacob Vlijm

Tôi thực sự ngưỡng mộ "niềm đam mê" của bạn :) ... nhưng vẫn còn một vấn đề với gnome-terminal. Một cho 1, hai cho 1, ba cho 2, bốn cho 3, v.v. với các tab của nó. xterm và mate-terminal dường như vẫn hoạt động tốt.
GreggD

@TedM. Cảm ơn đã đề cập! Câu hỏi ngớ ngẩn, nhưng bạn có chắc bạn sử dụng mã mới nhất? Trên Mate 15.10 tất cả các bài kiểm tra tôi chạy công việc không có ngoại lệ. Phiên bản Mate của bạn là gì? Trên Unity mọi thứ đã hoạt động tốt.
Jacob Vlijm

@TedM. Ngoài ra trên Mate 15.10 khá trống của tôi, nó được mặc định ở đó. Chỉ cần chạy lại các bài kiểm tra, hoàn hảo! Tôi có thể hỏi bạn vào ngày mai hoặc lâu hơn để chạy phiên bản chỉnh sửa của tập lệnh và đăng kết quả đầu ra ở đâu đó, để xem nguyên nhân gây ra ngoại lệ trong trường hợp của bạn không?
Jacob Vlijm

1

Một awkcách:

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

Giải trình:

Trong 1 lệnh lệnh trên, awkđược sử dụng để tìm số lượng thiết bị đầu cuối. Bên trong awkchương trình, nó chỉ kiểm tra số dòng trả về bởi lệnh ai - 1.


cái này trả về 0 cho tôi, điều này rõ ràng không đúng sự thật ...
Zanna

Cái này hoạt động rất tốt cho thiết bị đầu cuối & xterm của tôi, có vẻ như chống đạn.
GreggD

Chính xác : who | awk 'END{print NR - 1}', vì những gì bạn muốn là số dòng - 1.
muru

0

Cách đơn giản cũng có thể chỉ là chạy System Monitor(nếu bắt đầu từ Terminal bạn phải viết gnome-system-monitor) và trong tab "Quy trình" sắp xếp các quy trình đang chạy theo Tên và hơn là đếm số lần xuất hiện Bashtrong danh sách (chúng sẽ kết hợp với nhau nếu bạn sắp xếp theo tên, vì vậy nó dễ dàng để đếm).

Lưu ý rằng bạn phải tìm Bashvà không tìm Gnome Terminalnếu bạn muốn xem số lượng thiết bị đầu cuối được mở bởi người dùng. Khi bạn mở Terminal Gnome Terminalcũng sẽ xuất hiện trong danh sách Quy trình nhưng sẽ chỉ còn một thiết bị ngay cả khi có nhiều Thiết bị đầu cuối được mở. Nút "Xem" trong System Monitorcho phép bạn đặt quy trình nào sẽ xem, ví dụ: Tất cả quy trình / Quy trình người dùng / Hoạt động ...


Vì OP muốn sử dụng kết quả để tự động đặt (các) màu thiết bị đầu cuối, nên đây có vẻ không phải là một lựa chọn thực sự phù hợp.
Jacob Vlijm

Xin lỗi tôi thấy bây giờ anh ấy muốn sử dụng nó trong kịch bản. Nhưng sau đó sẽ ps -ef | Tên người dùng grep | grep bash | grep -v grep | wc -l không hoạt động?
NonSt ChuẩnModel
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.