Найдите бесплатный номер дисплея X11

У меня есть некоторые модульные тесты, которым нужен X11-дисплей, поэтому я планирую запустить Xvfb перед их запуском, но для запуска Xvfb мне понадобится бесплатный номер дисплея для его подключения. Мое лучшее предположение - посмотреть, что бесплатно в /tmp/.X11-unix, но я не уверен, как справиться с гонкой, если многие тесты пытаются начать одновременно.

sshd должен это сделать, знает ли кто-нибудь, как?

Ответ 1

С полным доверием этот ответ к соответствующему вопросу Насколько высока цифра отображения X11?:

Недавние серверы X с версии 1.13 (Xvfb тоже) поддерживают параметр командной строки -displayfd <fd>: он заставит X-сервер выбрать сам экран и записать номер дисплея обратно в дескриптор файла <fd>. Это немного запутанно, но это было бы безопасным и беспроблемным способом попросить Xvfb использовать любой бесплатный дисплей. Пример bash:

exec 6>display.log
Xvfb -displayfd 6
# The display number of the new Xvfb instance has been written to display.log 
# Kill Xvfb
exec 6>&-

Ответ 2

Почему бы не использовать тот факт, что каждый сервер X11 помещает файл "Lock" в /tmp?

Это называется /tmp/.Xn -lock, где "n" - это идентификатор отображения. (Также обратите внимание на ведущее. В имени файла).

Это механизм, который сам Xserver использует для проверки дублирования, и он кажется последовательным на всех платформах * nix, которые я пробовал (HP-UX, Linux,...)

Итак, вы можете адаптировать ваш script таким образом (простите меня за синтаксические ошибки, я не привык к оболочке C, чем скрипты оболочки Bourne/Korn)

DISPLAY_NUM=0

do

  if ( -e /tmp/.X$DISPLAY_NUM-lock ) then

     let DISPLAY_NUM=$DISPLAY_NUM+1

  else

     Xvfb :$DISPLAY_NUM -screen 0 1280x1024x24 -ac   (or whatever args take your fancy)

  fi

done

Ответ 3

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

#!/bin/bash
DISPLAY_NUM=0
unset TEST_HAS_RUN
until [ $TEST_HAS_RUN ] || (( $DISPLAY_NUM > 10 ))
do
 Xvfb :$DISPLAY_NUM &
 jobs
 sleep 2  # assumption here is that Xvfb will exit quickly if it can't launch
 if jobs | grep Xvfb
 then  
   echo launching test on :$DISPLAY_NUM
   xterm -display :$DISPLAY_NUM
   TEST_HAS_RUN=1
   kill %-
 else   
   let DISPLAY_NUM=$DISPLAY_NUM+1
 fi
done

Ответ 4

Основано на ответе @karunski.

Использование Xvfb для проверки дисплеев и для проверки того, являются ли UNIX-сокеты в процессе Xvfb более эффективным, обратите внимание, что параметр sleep 0.5 может быть переменным, зависит от машины.

#!/bin/bash
DISPLAY=0

until [ $DISPLAY_NUM > 10 ]; do
        echo -n "Looking for display on $DISPLAY..."
        Xvfb :$DISPLAY > /dev/null 2>&1 &
        pid=$!
        sleep 0.5
        lsof -a -U -p $pid  > /dev/null 2>&1    

        notfound="$?"
        kill $pid > /dev/null 2>&1

        wait $pid

        [ "$notfound" == "0" ] && echo "found" && break

        echo "fail"
        let DISPLAY=DISPLAY+1
done

Ответ 5

Возможно, это немного не по теме, но если вы используете xvfb-run для запуска команды, требующей Xserver, просто запустите

# xvfb-run -a your command

делает трюк.