Как программно проверить, можно ли подключиться к X-серверу, указанному в $ DISPLAY?

8

Это что-то среднее между программированием и администратором сервера, но в конечном итоге это кажется наиболее подходящим местом для этого.

Я ищу способ определить, является ли переменная ' $DISPLAY' рекламирующим XServer, к которому мы можем фактически подключиться, то есть, если вся аутентификация и еще много чего есть для выполнения дальнейших действий.

В идеале я ищу какой-то инструмент оболочки, который возвращает true / false, который можно использовать в скрипте сборки, чтобы определить, должны ли выполняться другие тесты в нем (которые я не контролирую) или нет.

В настоящее время тесты просто проверяют envпеременную " $DISPLAY", и, если она есть, будут пытаться соединиться, и, когда соединение не работает, тесты предполагают неудачу теста, а не просто дисплей не подключается.

Мне просто нужно уметь

if [[ ! can_connect_to_X ]] ; then 
    unset DISPLAY
fi

Для того, чтобы остановить эти тесты, имеющие серьезные проблемы с психикой

В идеальной ситуации инструмент, необходимый для этого, должен поставляться с самими библиотеками X Client, чтобы не вызывать особых зависимостей, и чтобы можно было предположить, что если утилиты нет, мы не можем подключиться ни к какому дисплею.

Кент Фредрик
источник

Ответы:

6

Вы можете попробовать с командой xset:

if [[ ! $(xset -q) ]]; then
   # the X server is not reachable
else
   # the X server is reachable
fi
slubman
источник
Хотя в итоге я использовал его более сложным способом, скорее всего, xset установлен, а не xdpyinfo.
Кент Фредрик
2

Я предполагаю, что есть лучшее решение. Но вы всегда можете просто использовать небольшой инструмент, такой как xclock, и проверить состояние выхода.

if [[ ! xclock ]]; then
  exit 1
fi
pkill xclock

Но человек, что это некрасиво :-)

Менее хаки, поместите в checkX.c следующее:

#include <X11/Xlib.h>
#include <stdio.h>

int main() 
{
    Display *display;
    if( ! (display=XOpenDisplay(NULL) ) ) {
        return(1);
    }
    return 0;
}

Затем:

gcc -lX11 checkX.c -o checkX
chmod +x checkX

И, наконец:

if ./checkX; then
   echo "We are good to go!"
fi
Кайл Брандт
источник
Да, это первое, что я рассмотрел, но я хотел что-то, что визуально не создавало окно: /. Я даже подумывал сделать xclock &, а затем убить его.
Кент Фредрик
xclock -geometry 1x1 - это лучшее, что я могу сделать для устранения визуального вторжения: /, но оно также выделяет пространство задач на панели задач :(
Кент Фредрик,
Это первая X-программа, которую я когда-либо писал на C, так что не уверен, что она абсолютно надежна :-)
Кайл Брандт,
И не самая портативная вещь ;-)
Кайл Брандт
Это очень удобно, просто, к сожалению, мои ограничения несколько жестче. По правде говоря, я пишу ebuild (gentoo), поэтому я должен виртуально делать / everything / in shell и предполагать, что приложения будут там раньше, и я не могу просто заранее добавить двоичные двоичные объекты в сторонние приложения. :)
Кент Фредрик
1

Вот возможный WayToDoIt, хотя я не уверен, насколько он хорош.

  x_works(){
     # If there is no xdpyinfo
     # Bash will return 127
     # If X cant connect, it returns 1
     # If X can connect, it returns 0
     xdpyinfo 1>/dev/null 2>&1
     WORKS="$?"
     return $WORKS
  }

  if x_works; then 
   ...

Это кажется , работает.

Кент Фредрик
источник
На моей машине с Fedora 11 я получаю: $ xdpyinfo 1 использование: xdpyinfo [опции] В любом случае, я думаю, что это хорошая идея использовать программу xdpyinfo.
Кристиан Чиупиту
'1' - это перенаправление stderr для bash;), а не для параметра xdpyinfo :)
Кент Фредрик,