如何检查X服务器是否正在运行?


74

有没有办法找出当前会话用户是否正在运行Xserver(在Linux下)?

我从以下事情开始:

ps -e | grep X 

但这并不总是有效

我尝试的另一件事是检查$DISPLAY变量

还有其他方法可以检查吗?

编辑:有人建议使用$ DISPLAY变量,但是如果用户摆弄这个变量怎么办?如果他尝试执行某项操作并更改此变量,然后在我检查它时,它将不再反映系统的准确状态该怎么办?是否有特定方法可以始终返回正确答案?

我发现可以通过编程方式完成:

#include <X11/Xlib.h> 
int main()
    { exit(XOpenDisplay(NULL) ? 0 : 1);  } 

$ gcc -o xprobe xprobe.c -L/usr/X11R6/lib -lX11 

但是我正在寻找一种脚本方式。


2
为什么“ ps -e | grep X”不总是有效?
stephendl

2
为什么$ DISPLAY不起作用?
马修·马歇尔

@stephendl:我发现在某些情况下X正在运行,但是用户通过没有X的终端连接。
RomanM

只是个小问题:在C程序中调用exit()测试X是没有意义的,只需返回状态就可以了。
放松

5
还有一点... XOpenDisplay在内部使用了DISPLAY环境变量。
Petesh

Answers:


65

我经常需要在运行许多X服务器的服务器上运行X命令,因此ps基于答案的命令不起作用。自然,$DISPLAY必须适当设置。要检查它是否有效,请使用以下xset q片段:

if ! xset q &>/dev/null; then
    echo "No X server at \$DISPLAY [$DISPLAY]" >&2
    exit 1
fi

我认为这比使用“更好” xpropxdpyinfo因为它xset产生的食用量更少/dev/null。OP应接受此答案。
jamadagni

当$ DISPLAY地址上根本没有运行X服务器时xset,实际上所有的X命令都挂起了。有没有办法设置超时时间?

1
@will这个挂起不会特定于xset。任何X程序都会遭受它的困扰。挂起取决于X传输。如果您DISPLAY=:1说的话,这意味着tcp端口为6001。您可能监听了一些红色进程。xset当没有人在听时,我会立即返回。
bobbogo

很好,但是为什么吵呢?即使将stdout和stderr重定向到/ dev / null,我仍会收到“ connect /tmp/.X11-unix/X1:无此类文件或目录”的消息。我跟踪了它,它似乎没有被xset写入。我也跟踪了相关的sshd,它似乎也没有写它。xset,xdpyinfo和原始问题中的测试程序都输出此无用的错误消息。
dstromberg

@dstromberg对于这个问题,这是一个非常不合适的地方!然而:它看起来像你对我是SSH-ING从本地机器的本地到远程机器的远程,在你打开X转发SSH。问题是原始的ssh命令需要访问工作的X服务器,并且在我看来,您$DISPLAYlocal的设置错误。然后发生的事情是您在remote上运行X命令。ssh将X协议通过隧道传输回本地,该协议失败(由于dodgy $DISPLAY),并且ssh打印消息。
bobbogo

18

$ DISPLAY是标准方式。这就是用户如何与要使用哪个X服务器的程序进行通信的方式。


但是如果用户摆弄这个变量怎么办?如果他尝试执行某项操作并更改此变量,然后在我检查它时,它将不再反映系统的准确状态该怎么办?有没有具体的方法可以做到这一点?
RomanM

4
如果设置$ DISPLAY,那是因为我希望您的程序转到其他显示。您想对用户的显式配置进行第二次猜测的用例是什么?您是否还要避免使用$ HOME以防用户弄乱它?它在哪里结束?

2
您想访问哪个X服务器?我不得不不得不在远程系统上安装驱动程序。另外,在POSIX中,XOpenDisplay(NULL)被定义为简单地读取$ DISPLAY,因此,充其量听起来好像您是在指望非标准行为。

5
我的意思是,如果在本地主机上运行一个,但是由于它们是远程登录,他们将$ DISPLAY设置为另一台服务器,您是否仍要使用“本地”服务器?如果本地不止一个怎么办?我不知道您将如何检测到它,或者为什么要这么做。$ DISPLAY存在是有原因的。

1
您能否为非Linux世界的用户提供答案?什么是$ DISPLAY?如何使用它?
保罗

9

我用

pidof X && echo "yup X server is running"

pgrep和$ DISPLAY是其他选项。

其他注意事项:

su则不会设置$ DISPLAY。更改程序运行环境的操作可能会使此操作不起作用。

我不要求ps -e | grep X,因为它将找到procX,而不是X服务器。


这与ps -e不同吗?grep X吗?AFAIK pidof只是killall5的别名,并不总是在所有系统上都定义
RomanM

来自man pidof:“ pidof实际上是与killall5相同的程序;该程序的行为取决于调用它的名称。” pidof的行为与killall5不同。如果您使用的是旧的Unix系统,则可能不存在。
伊恩·凯灵

但是对于大约一百万种事物的旧的unix系统也可以说同样的话。
伊恩·凯林

8

我用来判断X是否正在运行的一个技巧是:

远程登录127.0.0.1 6000

如果连接成功,则说明您正在运行X服务器,并且该服务器正在接受入站TCP连接(这些天通常不是默认设置)...。


1
我猜目前,安全意识强的系统将没有telnet可用的命令。
boardrider

1
具有安全意识的系统也不会在TCP端口上侦听,但是会限制在Unix域套接字上,从而进一步使该方法无效。
alanc

8

您可以使用xdpyinfo(可以通过安装apt-get install x11-utils)。


6
xprop -root &> /dev/null 

...是我尝试过的真实命令,用于测试“ X-able”情况。并且,几乎可以肯定它可以在任何运行X的系统上运行,当然,如果仍然找不到该命令,则该命令将失败,因此,即使该命令不存在,您也可以假设没有X。(这就是为什么我使用&>而不是>的原因)


1
重新&>用于在dash不支持的shell脚本下运行时&>,可以使用>/dev/null 2>&1
jamadagni

1
在cygwin上,典型的安装X的方法是安装软件包xinit。因此,xprop不会自动安装,因为它不是依赖项。
Egor Skriptunoff 2016年

4

1)

#netstat -lp | grep -ix
tcp 0 0 *:x11 *:*听2937 / X          
tcp6 0 0 [::]:x11 [::]:*听2937 / X          
活动的UNIX域套接字(仅服务器)
Unix 2 [ACC]流侦听8940 2937 / X @ / tmp / .X11-unix / X0
UNIX 2 [ACC]流侦听8941 2937 / X /tmp/.X11-unix/X0
#

2)nmap

#nmap localhost | grep -ix
6000 / tcp打开X11
#

3

我写了xdpyprobe程序就是为了这个目的。与xset,xdpyinfo和其他常规工具不同,它不执行任何其他操作(仅检查X服务器并退出),并且可能不产生任何输出(如果指定了“ -q”选项)。


3

bash脚本解决方案:

if ! xset q &>/dev/null; then
    echo "No X server at \$DISPLAY [$DISPLAY]" >&2
    exit 1
fi

如果从另一个控制台(Ctrl + Alt + F?)或ssh登录,则不起作用。对我来说,这个解决方案可以在我的Archlinux中使用:

#!/bin/sh
ps aux|grep -v grep|grep "/usr/lib/Xorg"
EXITSTATUS=$?
if [ $EXITSTATUS -eq 0 ]; then
  echo "X server running"
  exit 1
fi

您只能为Xorg或系统上的适当命令更改/ usr / lib / Xorg。


在我的情况下,进程名称/usr/lib/xorg/Xorg改为/usr/lib/Xorg
ignacio

2

首先,您需要确保在服务器上正确安装了基础X11软件包:

rpm -qa | grep xorg-x11-xauth

如果不是,请安装所有软件包:

sudo yum install xorg-x11-xauth xterm

确保将openssh服务器配置为转发x11连接:

edit file : vim /etc/ssh/sshd_config

X11Forwarding yes

注意:如果该行之前带有注释(#)或设置为no,请更新文件以匹配上述内容,然后重新启动ssh服务器守护程序(请注意此处-如果发生错误,则可能会将自己锁定在服务器)

sudo /etc/init.d/sshd restart

现在,配置SSH应用程序以转发X11请求:

ssh -Y your_username@your_server.your_domain.com


0

这是用于检查的PHP脚本。

$xsession = `pidof X`;
if (!$xsession) {
    echo "There is no active X session, aborting..\n";
    exit;
}

类似的命令也可以在shell脚本中使用。就像pidof命令一样。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.