我正在实施 USB 插入/拔出通知(这里是相关问题),我需要执行类似notify-send "device plugged" "My Device Title". 问题是要使此命令起作用,我应该首先设置DISPLAY,如下所示:
export DISPLAY=":0.0"
Run Code Online (Sandbox Code Playgroud)
其次,该命令应该由适当的用户调用。说,对于用户dimon:
su dimon -c "notify-send 'device plugged' 'My Device Title'"
Run Code Online (Sandbox Code Playgroud)
因此,我需要获取所有活动 X 会话和适当用户的列表,并notify-send在他的DISPLAY.
我尝试为此使用wLinux 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
Run Code Online (Sandbox Code Playgroud)
所以我们有用户名和显示。我决定这样解析它:
declare -a logged_users=(`w |grep -vP "^(USER| )" |awk '{if (NF==8){print $1" "$3} else {print $1" :0"}}' |sort |uniq`)
Run Code Online (Sandbox Code Playgroud)
现在,我有 array logged_users: [0]containsdimon和[1]contains :0。这会很棒,但不幸的是它并不适用于所有地方。比如说,在带有 lightdm 的 Ubuntu 12.04 上,我们有这个w输出:
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
Run Code Online (Sandbox Code Playgroud)
不知道为什么gnome-session. 更糟糕的是,在 xubuntu:
USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT
nui tty7 15:50 31:07 52.55s 0.13s /bin/sh /etc/xd
Run Code Online (Sandbox Code Playgroud)
完全没有显示!如果其他用户登录,也不会为他指定显示(但实际上是:1.0)
所以,我正在寻找另一种方法。我也知道我们在这里有一个所有活动 X 会话的列表:/tmp/.X11-unix,我可以像这样获得它们的列表:
cd /tmp/.X11-unix && for x in X*; do echo ":${x#X}"; done
Run Code Online (Sandbox Code Playgroud)
但是,我不知道如何检索用户。
那么,如何获取所有活动 X 会话和适当用户的列表呢?
这是针对本地X 服务器用户的解决方案(忽略具有远程或虚拟 X 服务器的本地 X 客户端)。
您确定显示管理器的 PID(这是 Xorg 的父 PID),确定其子进程的 PID,并确定以其中一个进程为父进程的所有进程的用户:
#! /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}'
Run Code Online (Sandbox Code Playgroud)