我有一个从 udev
运行的脚本当我插入外部驱动器时。它总是有效。但是从 升级后Linux 3.8/Xorg 1.12/Mint 14 ( Ubuntu 12.10 兼容)到 Linux 3.11/Xorg 1.14/Mint 16 ( Ubuntu 13.10 兼容),它不再起作用。
该脚本仍在运行,但需要显示的命令都不起作用。我通过退出 udev
来解决这个问题守护进程并手动运行 udevd --debug
用于详细输出(更多信息见下文)。
该脚本曾经在 中工作薄荷 14/12.10 :
export DISPLAY=:0
UUID=$1
DEV=$2
notify-send -t 700 "mounting $DEV ($UUID)"
gnome-terminal -t "Backing up home..." -x rsync long line of data
zenity --warning --text="Done."
但现在不在 薄荷 16/13.10 .如果您想知道可能的解决方案,我逐渐添加了一些东西,现在看起来像这样:
export DISPLAY=:0.0
xhost +local:
xhost +si:localuser:root
xhost +
DISPLAY=:0.0
export DISPLAY=:0.0
UUID=$1
DEV=$2
notify-send -t 700 "mounting $DEV ($UUID)"
gnome-terminal -t "Backing up home..." -x rsync long line of data
zenity --warning --text="Done." --display=:0.0
但它仍然不起作用。
udevd --debug
仍然显示这个:'(err) 'No protocol specified'
'(err) ''
'(err) '** (gnome-terminal:24171): WARNING **: Could not open X display'
'(err) 'No protocol specified'
'(err) 'Failed to parse arguments: Cannot open display: '
'(err) 'No protocol specified'
'(err) ''
'(err) '** (zenity:24173): WARNING **: Could not open X display'
'(err) 'No protocol specified'
'(err) ''
'(err) '(zenity:24173): Gtk-WARNING **: cannot open display: :0.0'
'(err) 'No protocol specified'
请注意,任何 bash 逻辑都有效。将测试变量回显到
>>/tmp/test.log
作品。它只是访问不再工作的显示器。这真让我抓狂。现在实现这一目标的正确方法是什么?
更新 2013-12-20
所以,在之前的 Ubuntu 中,
X
命令会自动找到通往当前 X
的路使用用户。现在,我似乎每次都需要这两件事:
X
使用用户:xhost +si:localuser:root
root/udev
边:X
使用用户的~/.Xauthority
文件到 /root
这“感觉”就像是时光倒流。这仅在我每次以同一用户身份登录时才有效,因此我可以复制
.Xauthority
脚本执行时该用户家中的文件。旧的 Ubuntu 使用什么“技巧”来自动“神奇”地完成这项工作?
最佳答案
好的,我写这个答案是为了尝试阐明 X 服务器的安全模型,正如我所理解的。我不是这方面的专家,所以我可能弄错了一些(很多?)。此外,正如 OP 所指出的那样,在不同的发行版中,甚至同一发行版的不同版本中,许多事情都是不同的。
获得授权连接到 X 服务器的主要方法有两种:
xhost
方式(Host Access):服务器维护一个允许连接到服务器的主机、本地用户、组等列表。 xauth
方式(基于 Cookie):服务器有一个随机生成的 cookie 列表,任何显示这些 cookie 之一的人都将被授予访问权限。 现在,分发特定的东西......
当 X 服务器由启动系统启动时,通常会传递一个形式为
-auth <filename>
的命令行。 .此文件包含用于授权的初始 cookie 列表。它是在 X 服务器运行之前使用 xauth
创建的。工具。然后就在 X 服务器之后,启动登录管理器,并指示它从同一个文件中读取 cookie,以便它可以连接。现在,当用户
rodrigo
登录,它必须被授权连接到服务器。这是由登录管理器完成的,它有两个选项:xhost +si:localuser:rodrigo
. $HOME/.Xauthority
中(新用户的家)。 /var/run/gdm/auth-for-rodrigo-xxxx
)和环境变量 XAUTHORITY
设置为该文件的名称。 此外,它可以做两件事。一些登录管理器甚至默认将 root 用户添加到授权用户列表中(就像
xhost +si:localuser:root
一样)。但请注意,如果您无权连接到 X 服务器,则无法将自己添加到列表中(例如运行
xhost +
)。道理和没有 key 就不能从外面打开房门的道理是一样的……就算你是root也是如此!这是否意味着root用户无法连接到服务器?绝对不!但是首先你必须知道如何配置登录的用户以连接到服务器。对于以登录用户身份运行:
$ xhost
它将显示一条消息和授权用户、主机或组的列表(如果有):
access control enabled, only authorized clients can connect
SI:localuser:rodrigo
然后运行:
$ echo $XAUTHORITY
查看授权文件的保存位置。如果为空,则为
~/.Xauthority
.然后:$ xauth list :0
查看您的授权 cookie 列表。
现在,如果服务器中有任何 cookie,root 用户应该能够连接,使 XAUTHORITY 环境变量指向正确的 cookie 文件。请注意,在许多设置中,登录管理器的 cookie 也会保留。只是寻找它!
root 访问的另一种可能性是修改
Xsession
文件添加命令 xhost +si:localuser:root
并获得永久访问权限。详细信息因使用的特定程序而异,但对于 gdm
您只需在 /etc/gdm/Init/
中添加一个可执行脚本即可与 xhost
命令,它将在下次启动时自动运行。PS:您可以使用
sudo -i
检查您对 X 服务器的 root 访问权限,但请注意有些 sudo
配置可能会保留 DISPLAY
, XAUTHORITY
或 HOME
变量并修改测试结果。示例 :此脚本应该能够以 root 用户身份将您连接到 X 服务器
export DISPLAY=:0
export XAUTHORITY=`ls /var/run/gdm/auth-for-gdm-*/database`
xrandr #just for show
自然,路径为
XAUTHORITY
变量将取决于您使用的登录管理器(问候语)。您可以使用用户文件(您说它在 /home/redsandro/.Xauthority
中,但我不太确定)。或者您可以使用欢迎曲奇。要获取迎宾 cookie,您可以使用以下命令:$ pgrep -a Xorg
在我的系统中给出:
408 /usr/bin/Xorg :0 -background none -verbose -auth /var/run/gdm/auth-for-gdm-gDg3Ij/database -seat seat0 -nolisten tcp vt1
所以我的文件是
/var/run/gdm/auth-for-gdm-gDg3Ij/database
. gDg3Ij
是随机的,每次服务器重启都会改变,这就是 ls ...
的原因诡计。使用 GDM cookie 而不是用户的好处是它不依赖于登录的用户。它甚至可以在没有用户的情况下工作!
更新 :从您的最新评论中,我看到您的 X 服务器命令是:
/usr/bin/X :0 -audit 0 -auth /var/lib/mdm/:0.Xauth -nolisten tcp vt8
所以有用于启动登录管理器的 cookie 的名称。如果我是对的,如果您能够阅读该文件,那么它应该一直可用。而且您是 root 用户,因此,以下几行应该足以让您以 root 用户身份访问显示内容:
export DISPLAY=:0
export XAUTHORITY=/var/lib/mdm/:0.Xauth
zenity --info --text 'Happy New Year'
关于linux - 从 udev 启动的脚本不再具有 DISPLAY 访问权限?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20395027/