我有一些需要X11显示器的单元测试,所以我计划在运行之前启动Xvfb,但是为了启动Xvfb,我需要一个免费的显示号码来连接它。我最好的猜测是看/tmp/.X11-unix
中有什么是免费的,但如果很多测试试图同时开始,我不知道如何处理比赛。
sshd必须这样做,有谁知道怎么做?
答案 0 :(得分:12)
为什么不利用每个X11服务器将“Lock”文件放入/ tmp?
的事实这称为/tmp/.Xn-lock,其中“n”是显示ID。 (另请注意文件名中的前导。)
这是Xserver本身用于检查重复的机制,它在我尝试过的所有* nix平台上看起来都是一致的(HP-UX,Linux,...)
所以你可以调整你的脚本(请原谅我的语法错误,我不习惯使用C shell而不是Bourne / Korn shell脚本)
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
答案 1 :(得分:9)
对this answer相关问题的How high do X11 display numbers go?完全归功于:
最新的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 :(得分:5)
试图找到一个免费的显示号码是没有意义的。正如您所猜测的那样,在您找到一个免费的时间和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
答案 3 :(得分:1)
可能有点偏离主题,但是如果您使用xvfb-run
启动需要Xserver的命令,则只需运行
# xvfb-run -a your command
起到了作用。
答案 4 :(得分:0)
基于@karunski的回答。
使用Xvfb来探测显示,并使用lsof检查Xvfb进程中的unix套接字是否更有效,请注意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 :(得分:0)
这对我有用(注意 - 使用 bash)
exec {lock_fd}>/var/lock/xlockfile || exit 1
flock -n "$lock_fd" || { echo "ERROR: flock() failed." >&2; exit 1; }
DISPLAY_NUM=1
until [[ $xvfb ]]; do
if [[ -e /tmp/.X$DISPLAY_NUM-lock ]]; then
let DISPLAY_NUM=$DISPLAY_NUM+1
else
Xvfb :$DISPLAY_NUM -ac -screen 0 $XVFB_WHD -nolisten tcp &
xvfb=$!
fi
done
flock -u "$lock_fd"
注意向外锁只有在所有运行 xvfb 命令的脚本都使用它时才起作用,否则你会再次遇到竞争条件