我有一些需要 X11 显示的单元测试,所以我计划在运行它们之前启动 Xvfb,但是要启动 Xvfb,我需要一个空闲的显示器号码来连接它。 我最好的猜测是查看 /tmp/.X11-unix
中的可用情况,但是我不确定如何处理如果多个测试同时尝试启动的竞争。
sshd 必须这样做,有人知道怎么做吗?
我有一些需要 X11 显示的单元测试,所以我计划在运行它们之前启动 Xvfb,但是要启动 Xvfb,我需要一个空闲的显示器号码来连接它。 我最好的猜测是查看 /tmp/.X11-unix
中的可用情况,但是我不确定如何处理如果多个测试同时尝试启动的竞争。
sshd 必须这样做,有人知道怎么做吗?
以下是关于相关问题How high do X11 display numbers go?的答案(原答案)的完整引用:
截至1.13版(包括Xvfb
),最近的X服务器支持命令行选项-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>&-
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
试图找到免费的显示号码是没有意义的。正如你所猜测的那样,在你找到一个空闲的号码并且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
xterm
成功启动,它不会阻塞您的脚本,直到用户手动退出。否则,似乎 TEST_HAS_RUN
永远不会被设置,循环永远不会退出。实际上,如果 xterm
无法启动,您的测试看起来是 通过 的。我有什么遗漏吗? - user2975337jobs | grep Xvfb
)。最好使用唯一的fbdir(例如-fbdir /var/tmp/$0.$$.$RANDOM
)启动Xvfb,然后检查该目录中的文件Xvfb_screen0
。 - user2975337也许有点跑题,但如果您使用xvfb-run
来启动需要X服务器的命令,那么只需要运行
# xvfb-run -a your command
做到了。
基于@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
这对我有用(注意 - 使用bash)
exec {lock_fd}>/var/lock/xlockfile || exit 1
flock "$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
v1.14可在jessie
中使用,这意味着在平均发行版中应该相当新(2013年下半年或之后)。 - dma_k