Làm cách nào để có được danh sách tất cả các phiên X hoạt động và chủ sở hữu của chúng


5

Tôi đang triển khai thông báo cắm / rút USB ( câu hỏi liên quan ở đây ) và tôi cần thực hiện một cái gì đó như notify-send "device plugged" "My Device Title". Vấn đề là để làm cho lệnh này hoạt động, trước tiên tôi nên đặt DISPLAY, như thế này:

export DISPLAY=":0.0"

Và thứ hai, lệnh này nên được gọi bởi người dùng thích hợp. Nói, cho người dùng dimon:

su dimon -c "notify-send 'device plugged' 'My Device Title'"

Vì vậy, tôi cần lấy danh sách tất cả các phiên X hoạt động và người dùng phù hợp và gọi notify-sendcho từng người dùng trên đó DISPLAY.

Tôi đã cố gắng sử dụng wcho điều đó, ví dụ đầu ra tại Linux Mint 13 MATE:

USER     TTY      FROM              LOGIN@   IDLE   JCPU   PCPU WHAT
dimon    tty8     :0               Sun15    3days  1:38m  1.95s x-session-manager
dimon    pts/0    :0               Sun15    0.00s  0.20s  0.00s tmux

Vì vậy, chúng tôi có cả tên người dùng và hiển thị. Tôi quyết định phân tích nó như thế:

declare -a logged_users=(`w |grep -vP "^(USER| )" |awk '{if (NF==8){print $1" "$3} else {print $1" :0"}}' |sort |uniq`)

Bây giờ, tôi có mảng logged_users: [0]chứa dimon[1]chứa :0. Điều này sẽ là tuyệt vời, nhưng tiếc là nó hoạt động không phải ở khắp mọi nơi. Giả sử, trên Ubuntu 12.04 với lightdm, chúng ta có wđầu ra này :

USER     TTY      FROM              LOGIN@   IDLE   JCPU   PCPU WHAT
nui      tty7                      18:22   35:56   1.66s  0.11s gnome-session -
nui      pts/0    :0.0             18:55    5.00s  0.20s  0.00s w

Không biết tại sao không có giá trị TỪ cho gnome-session. Và thậm chí tệ hơn, tại xubfox:

USER     TTY      FROM              LOGIN@   IDLE   JCPU   PCPU WHAT
nui      tty7                      15:50   31:07  52.55s  0.13s /bin/sh /etc/xd

Không có màn hình nào cả! Nếu người dùng khác đăng nhập, không có màn hình nào được chỉ định cho anh ta (nhưng thực tế là vậy :1.0)

Vì vậy, tôi đang tìm kiếm một cách tiếp cận khác. Tôi cũng biết chúng tôi có một danh sách tất cả các phiên X đang hoạt động ở đây: /tmp/.X11-unixvà tôi có thể lấy danh sách của chúng như thế này:

cd /tmp/.X11-unix && for x in X*; do echo ":${x#X}"; done

Nhưng sau đó, tôi không biết làm thế nào để lấy người dùng.

Vậy, làm thế nào để có được danh sách tất cả các phiên X hoạt động và người dùng phù hợp?

Câu trả lời:


4

Đây là một giải pháp cho người dùng máy chủ X cục bộ (bỏ qua các máy khách X cục bộ với máy chủ X từ xa hoặc ảo).

Bạn xác định PID của trình quản lý hiển thị (là PID gốc của Xorg), xác định các PID của con của nó và xác định người dùng của tất cả các quy trình có một trong số chúng là cha mẹ:

#! /bin/bash
xorg_pid=$(pidof -s /usr/bin/Xorg)
test -n "$xorg_pid" || exit 1
dm_pid=$(ps -eo pid,ppid,args | \
    awk -v xorg_pid=$xorg_pid '$1 == xorg_pid {print $2}')
pid_list="$(ps -eo pid,ppid,cmd | \
    awk -v dm_pid=$dm_pid '$2 == dm_pid {if (matchnr == 0) '\
'{ printf "%s%d ","$2 == ",$1; matchnr++;} '\
'else printf "%s%d ","|| $2 == ",$1;}')"
ps -eo pid,ppid,user,cmd | awk "$pid_list"'{print $3}'

Điều gì nếu bạn sử dụng pgrep Xorgthay thế. Tôi có 2 chạy bây giờ, làm thế nào điều này sẽ xử lý bội số?
slm

@slm Bạn không tình cờ đã thử mã ...?
Hauke ​​Laging

Tất nhiên tôi đã làm. Tôi thấy rằng nó chỉ tìm thấy một.
slm

@slm Đó là ý định. Tất cả các trường hợp có cùng cha mẹ (ít nhất đó là giả định về tập lệnh của tôi), do đó chỉ sử dụng lần truy cập đầu tiên là đủ. Tôi cũng có hai phiên bản Xorg đang chạy. Sẽ rất khó để kiểm tra mã như vậy nếu không ...
Hauke ​​Laging 26/214

Có lẽ tôi đang bối rối, không phải anh ấy muốn xem tất cả tên người dùng đang chạy X sao?
slm

2

Tôi đã có cùng một vấn đề thông báo-gửi.

Phương pháp này (cũng được đăng ở đây ) sử dụng thông tin môi trường ps ecung cấp. ps e -u username | sed -rn 's/.* DISPLAY=(:[0-9]*).*/\1/p'đưa ra một danh sách tất cả các số HIỂN THỊ trong môi trường của tất cả các quy trình của tên người dùng .

Nếu có một cửa sổ sở hữu gốc trên máy tính để bàn của bạn thì root cũng sẽ có một số quy trình có cùng số HIỂN THỊ, nhưng nếu không thì một HIỂN THỊ chỉ nên được liên kết với một người dùng. (Không phải cách khác - ngay bây giờ tôi đã đăng nhập vào hai tty với hai phiên X, vì vậy tôi đang sử dụng cả hai: 0 và: 1.)

Mã này sẽ xuất ra tất cả các HIỂN THỊ hiện đang sử dụng (do đó tất cả các phiên X) của tất cả người dùng đang đăng nhập. (root bị bỏ qua)

Lưu ý sudovề pslệnh: quyền root là cần thiết để xem các môi trường của các quá trình của người dùng khác. Tất nhiên, nếu tập lệnh được chạy bởi root thì không cần thiết.

Tên người dùng và số hiển thị được sử dụng làm chỉ số của mảng kết hợp để chỉ giữ các giá trị duy nhất.

#!/bin/bash

declare -A disps usrs
usrs=()
disps=()

for i in $(users);do
    [[ $i = root ]] && continue # skip root
    usrs[$i]=1
done # unique names

for u in "${!usrs[@]}"; do
    for i in $(sudo ps e -u "$u" | sed -rn 's/.* DISPLAY=(:[0-9]*).*/\1/p');do
        disps[$i]=$u
    done
done

for d in "${!disps[@]}";do
    echo "User: ${disps[$d]}, Display: $d"
    #sudo -u "${disps[$d]}" DISPLAY="$d" notify-send "Title" "Message"
done

Dòng nhận xét cuối cùng cho thấy cách gửi thông báo có thể được gọi.

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.