![进一步阅读](https://linux22.com/image/105404/%E8%BF%9B%E4%B8%80%E6%AD%A5%E9%98%85%E8%AF%BB.png)
openSUSE Leap 42.2 Gnome 终端 3.20.2
我打开了一个终端窗口。如果我输入以下命令:
gnome-terminal
作为非 root 用户,它成功启动了一个新终端。
但是,如果我以 root 身份运行该命令,则会收到以下错误消息:
为 org.gnome.Terminal 构建代理时出错:/org/gnome/Terminal/Factory0:连接已关闭
如果我尝试启动终端,dbus-launch gnome-terminal
那么它就可以工作。
是什么阻止gnome-terminal
命令以 root 身份启动终端?是dbus-launch
一种可以接受的解决方法还是可能会导致不可预见的问题(我真的不明白它在做什么)?
答案1
还记得在 Win32 出现并废除它之前的 Win16 时代,Windows 应用程序主要是如何工作的:在有 和 的地方hInstance
,hPrevInstance
尝试运行许多应用程序的第二个实例只是将事情移交给第一个实例,这使事情变得困难命令脚本工具(如 Take Command),因为人们会第二次调用应用程序,它显然会作为添加的窗口出现在屏幕上,但就命令解释器而言,它刚刚运行的子进程立即退出?
GNOME 为 Linux 恢复了 Win16 行为。
GNOME Terminal 现在是一个客户端-服务器应用程序。该gnome-terminal
程序只是一个客户端,它构造桌面总线消息到服务器,传递其命令行选项、环境、工作目录和参数,然后简单地退出。服务器在桌面总线上gnome-terminal-server
注册org.gnome.Terminal
,负责所有实际的终端仿真并在 GUI 上显示窗口。
桌面总线客户端gnome-terminal
通过环境变量定位桌面总线代理,该环境变量通常指向每个用户目录中的套接字,例如/run/user/1001
.或者,环境变量指定在“当前用户的运行时目录”中查找,并且根据客户端进程的有效用户ID构造与前述类似的路径。无论哪种情况,该目录通常都是个人用户私有的,其他(非特权)用户无法访问。
当人们试图通过诸如此类的方式gnome-terminal
以另一个用户的身份运行时,就会发生热闹的事情。sudo
如果环境变量指向显式命名的运行时目录,则非特权客户端无法连接到每用户桌面总线。如果环境变量指向“当前用户的”运行时目录,它会查找错误的桌面总线代理,通常是该用户的代理目前没有由于用户尚未登录并启动该用户帐户的每用户服务而运行的桌面总线代理。 (每用户桌面总线代理由每用户服务管理器运行。每用户服务管理器要么显式启动,要么在某些服务管理软件的情况下,通过一些相当丑陋的挂钩进入由login
、su
和 SSH 服务器程序等。)
dbus-launch
作为超级用户对您有效的原因是dbus-launch
显式启动了另一个桌面总线代理,以超级用户身份运行,并且gnome-terminal
能够与之通信。幸运的是,系统还配置为gnome-terminal-server
当客户端尝试通过代理连接到服务器时请求启动服务器。 (情况不一定是这样,现在这种需求启动被视为一种较差的机制,因为它最终会导致大量桌面总线服务器进程不在任何类型的服务管理下运行。事实上,没有代理本身在服务管理下也被认为是低劣的,这通常也不被认为是一个好主意。超级用户帐户来运行此类服务,因为其中许多服务不希望以超级用户权限运行,因为他们希望在普通用户帐户的支持下运行。)
如果正如提问者所说“如何在无头服务器上远程启动 gnome-terminal? (无法通过X11转发启动)gnome-terminal
“确实,即使原始用户没有运行桌面总线代理,人们也会尝试运行。例如,当用户通过 SSH 登录但 SSH 登录过程不会启动每用户服务管理器时,就会发生这种情况,这又意味着每用户桌面总线代理未运行,并且gnome-terminal-server
无法通过桌面总线访问服务器(根据系统的配置方式,图形登录仍然可以触发启动每用户服务管理器,并且因此,人们可能会发现,以同一用户身份以图形方式登录会神奇地使事情正常工作,并且dbus-launch
会再次显式启动非服务管理的桌面总线代理。)
然而,当其中一个服务管理器能够连接到login
、su
和 SSH 服务器时,更多的欢笑就会随之而来。这些钩子通常实现启动每用户服务管理的语义,以及在该用户首次登录时启动的所有每用户服务;并在该用户最后注销时停止所有这些操作。如果有大量短暂且不重叠的 SSH 会话,那么在以下位置启动和关闭整个每用户服务管理系统(及其所有自动启动服务)可能会产生大量开销:每个 SSH 会话的开始和结束。 systemd 是这样的服务管理器之一,它的“徘徊”机制并不完美,只能真正解决一半问题。这意味着每用户服务管理在最终注销后“徘徊”,但它根本不会阻止每用户服务管理的启动。
进一步阅读
- 乔纳森·德博因·波拉德 (2016)。
/run/user/jim/dbus
。 《地名词典》。 小吃指南。软件。 jdebp.eu。 - 乔纳森·德博因·波拉德 (2016)。 ”每用户的用户服务”。 小吃指南。软件。 jdebp.eu。
- 运行真正的 gnome-terminal 多进程实例
- 使用户systemd服务持久化
- https://unix.stackexchange.com/a/323700/5132