我有一个脚本,从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
详细输出(下面更多)来解决这个问题.
此脚本曾用于Mint 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."
但不再是Mint 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
工作相呼应.它只是访问不再工作的显示器.
这真让我抓狂.现在实现这个目标的正确方法是什么?
因此,在之前的Ubuntu中,X
命令会自动找到当前X
使用用户的方式.
现在,我似乎每次都需要这两件事:
在X
使用用户:
xhost +si:localuser:root
在root/udev
旁边:
X
使用用户的~/.Xauthority
文件复制到/root
这种'感觉'就像是时光倒流一样.这仅在我每次以同一用户身份登录时编写脚本,因此我可以.Xauthority
在脚本执行时从该用户的主页复制该文件.
老Ubuntu使用什么'技巧'来完成自动'魔术'?
好的,正如我所理解的那样,我正在编写这个答案,试图澄清X服务器的安全模型.我不是这方面的专家,所以我可能有一些(很多?)错误.此外,正如OP所指出的,许多事情在不同的发行版中是不同的,甚至是相同发行版的不同版本.
获得授权连接到X服务器有两种主要方式:
该xhost
办法(主机访问):服务器维护被允许连接到服务器主机,本地用户,组,等的列表.
的xauth
(方式基于Cookie):服务器随机生成的Cookie的列表,任何人展示这些cookie中的一个将被授予访问权限.
现在,分发特定的东西......
当X服务器由启动系统启动时,通常会传递表单的命令行-auth <filename>
.此文件包含要用于授权的初始cookie列表.它是在使用该xauth
工具运行X服务器之前创建的.然后就在X服务器之后,登录管理器就会启动,并且它被指示从同一个文件读取cookie,因此它可以连接.
现在,当用户rodrigo
登录时,必须授权它连接到服务器.这是由登录管理器完成的,它有两个选项:
它相当于:xhost +si:localuser:rodrigo
.
它会生成另一个cookie,将其添加到服务器并将其传递给用户.这种传递可以通过两种方式完成:
它写在文件中$HOME/.Xauthority
(新用户的主页).
它写在其他地方(/var/run/gdm/auth-for-rodrigo-xxxx
),环境变量XAUTHORITY
设置为该文件的名称.
此外,它可以做两件事.一些登录管理器甚至默认将root用户添加到授权用户列表中(如同xhost +si:localuser:root
).
但请注意,如果您无权连接到X服务器,则无法将自己添加到列表中(xhost +
例如,运行).原因与你为什么不能在没有钥匙的情况下从外面打开房子的原因相同......即使你是根,也是如此!
这是否意味着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:您可以检查与X服务器的root访问权限sudo -i
,但要注意,有些sudo
配置可能会保留DISPLAY
,XAUTHORITY
或HOME
变量和修改测试的结果.
示例:此脚本应该能够以root身份将您连接到X服务器
export DISPLAY=:0 export XAUTHORITY=`ls /var/run/gdm/auth-for-gdm-*/database` xrandr #just for show
当然,XAUTHORITY
变量的路径取决于您使用的登录管理器(greeter).你可以使用用户文件(你说它在,/home/redsandro/.Xauthority
但我不太确定).或者您可以使用迎宾cookie.要获取greeter 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'