我可以以 root 身份在另一个用户的桌面上启动图形程序吗?

我可以以 root 身份在另一个用户的桌面上启动图形程序吗?

以下是我认为我需要了解的其他问题:

  • 来自非 X 会话? (意味着 root 没有登录到 X)

  • 如果多人登录 X,我是否可以自动检测谁在哪个屏幕上,从而以编程方式检测我需要在哪个屏幕上启动应用程序?

  • 我可以以用户身份启动应用程序吗? (好吧,我 99.999% 确定这是肯定的)

  • 能否检测X组的用户是否登录X?

答案1

要在用户桌面上启动图形程序,您需要找到两件事:用户桌面所在的显示器(地址)以及要使用的授权 cookie(密码)。

以下命令应列出用户在大多数 unice 上登录的本地显示(每行一个):

who | awk -v user="$target_user" '$1 == user && $2 ~ "^:" {print $2}'

找到授权cookie有点困难。您必须查找用户的 cookie 文件,这是~/.Xauthority默认的(您需要的只是 cookie 文件的位置,不需要从中提取 cookie)。这适用于许多系统,但不是全部;这取决于显示管理器及其设置方式,特别是 Gdm(Ubuntu 上的默认设置)没有使用我上次查看的默认位置。我想不出一种可移植的方法来找出实际的 X cookie 文件。最准确的查找方法是找出 X 进程的 pid 并查找该-auth选项的参数。另一种方法是找到在该 X 服务器上运行的进程并获取其XAUTHORITY环境变量。如果您在查找 cookie 文件时遇到问题,请参阅在远程 X 显示器上打开窗口(为什么“无法打开显示器”)?

获得这两条信息后,将所选的显示放入DISPLAY环境变量中,将所选的 X 权限 cookie 文件放入XAUTHORITY环境变量中,然后就完成了。程序以什么用户身份运行并不重要;su如果你愿意的话可以结合起来。

答案2

我不能完全尝试这个,因为我所有的机器都禁用了 root。

要查找用户所在的显示器,您可以使用该who命令。输出的最后一列通常是用户登录的 DISPLAY。像这样的东西可以用来只抓取显示(可能有一种更有效的方法来做到这一点,请随意提供编辑):

who | grep -m1 ^username.*\( | awk '{print $5}' | sed 's/[(|)]//g'

然后在该显示屏上启动图形 X 命令:

DISPLAY=:0 firefox &

其中 :0 将替换为您在第一个命令中找到的任何显示内容,而 firefox 将替换为您要运行的任何命令。您可以将其放入 shell 脚本中并仅使用变量。

下一部分是我尚未测试的部分,但我不明白为什么它不应该这样做:

su username -c "DISPLAY=:0 firefox"

以该用户身份启动 X 命令。

答案3

你可以看看 acpid 是如何做到的。例如,当它发出 xscreensaver 命令或为每个运行 X 或 X 会话的用户清空屏幕时。

例如在 Ubuntu 下此文件包含相关内容:

/etc/acpi/lid.sh

包含这个循环:

for x in /tmp/.X11-unix/*; do
    displaynum=`echo $x | sed s#/tmp/.X11-unix/X##`
    getXuser;
    if [ x"$XAUTHORITY" != x"" ]; then
        export DISPLAY=":$displaynum"
        grep -q off-line /proc/acpi/ac_adapter/*/state
        if [ $? = 1 ]
            then
            if pidof xscreensaver > /dev/null; then 
                su $user -c "xscreensaver-command -unthrottle"
            fi
        fi
        if [ x$RADEON_LIGHT = xtrue ]; then
            [ -x /usr/sbin/radeontool ] && radeontool light on
        fi
        if [ `pidof xscreensaver` ]; then
            su $user -c "xscreensaver-command -deactivate"
        fi
        su $user -c "xset dpms force on"
    fi
done

答案4

在我的研究中,我寻找一种优雅的方式来从有限的环境(例如 udev 规则)或超级用户中显示 GUI 或 X 任务,我最近创建了一个适合它的工具(更多细节)。

xpub是一个 shell 脚本,用于获取有关当前或给定 TTY 的 X 显示环境变量。

这是一个包含 udev 规则的示例:

IMPORT{program}="/usr/bin/xpub", \
RUN+="/bin/su $env{XUSER} -c '/usr/bin/notify-send Hello'"

$env{ENV}:如果当前tty用户启动X,否则将其删除。

使用命令行的原理是相同的export

export $(xpub) ; su ${XUSER} -c 'notify-send Hello'

相关内容