일부 JavaScript 단위 테스트를 수행하기 위해업도커 컨테이너 내부(우분투 14.04 기반)에서 다음을 사용합니다.카르마 스크립트 실행기그리고 xvfb-run
. 시작 스크립트는 다음과 같습니다.
#!/bin/bash
set -o errexit
# nasty workaround as xvfb-run doesn't cleanup properly...
trap "pkill -f /usr/lib/firefox/firefox" EXIT
xvfb-run --auto-servernum --server-args='-screen 0, 1024x768x16' firefox $1
브라우저를 시작하고 단위 테스트를 실행하면 정상적으로 작동합니다. 테스트를 실행한 후 karma는 생성된 브라우저 인스턴스를 종료합니다. 제 경우에는 xvfb-run을 통해 Firefox를 시작한 스크립트입니다.
위의 스크립트에서 trap
스크립트를 종료할 때 Firefox를 종료하는 프로그램을 등록한 것을 볼 수 있습니다. 이것은 작동하지만 스크립트는 종료되기 때문에 그다지 좋은 시민이 아닙니다.모두스크립트에 의해 시작된 인스턴스를 종료하는 것이 아니라 현재 실행 중인 Firefox 인스턴스입니다. 먼저 프로세스 종료를 시도했지만 xfvb-run
프로세스 종료는 스크립트에 의해 시작된 하위 프로세스에 아무런 영향을 미치지 않았습니다 xvfb-run
.
Firefox를 수동으로 시작하면 xvfb-run
여러 프로세스가 생성됩니다.
root@1d7a5988e521:/data# xvfb-run --auto-servernum --server-args='-screen 0, 1024x768x16' firefox &
[1] 348
root@1d7a5988e521:/data# ps ax
PID TTY STAT TIME COMMAND
1 ? Ss 0:00 bash
348 ? S 0:00 /bin/sh /usr/bin/xvfb-run --auto-servernum --server-args=-screen 0, 1024x768x16 firefox
360 ? S 0:00 Xvfb :99 -screen 0, 1024x768x16 -nolisten tcp -auth /tmp/xvfb-run.bgMEuq/Xauthority
361 ? Sl 0:00 /usr/lib/firefox/firefox
378 ? S 0:00 dbus-launch --autolaunch bcf665e095759bae9fc1929b57455cad --binary-syntax --close-stderr
379 ? Ss 0:00 //bin/dbus-daemon --fork --print-pid 5 --print-address 7 --session
388 ? S 0:00 /usr/lib/x86_64-linux-gnu/gconf/gconfd-2
414 ? R+ 0:00 ps ax
root@1d7a5988e521:/data#
지금 프로세스를 종료하면 xvfb-run
(PID 348) 다른 프로세스가 계속 실행되는 동안 해당 프로세스만 종료됩니다. Firefox 프로세스(PID 361)를 종료하면 xvfb-run
스크립트가 올바르게 종료되고 다른 프로세스도 종료됩니다. 하지만 내 스크립트에서는 프로세스의 PID만 알고 있습니다 xvfb-run
.
조사하다가 우연히 발견한이 다소 오래된 버그 보고서xvfb-run
버그 상태는 2012년에 수정되었지만 여전히 작동하는 것 같습니다.
xvfb-run
다른 프로세스가 적절하게 정리되도록 이 프로세스를 종료하는 정중한 방법이 있습니까 ?
Stack Overflow에 이 질문을 했지만 아직까지 답변을 얻지 못했습니다. Stack Overflow에 비해 약간 OT일 수도 있지만 여기가 더 나은 위치인가요? !
답변1
xvfb-run
그냥 기능 때문에 사용하는 것 같네요 --auto-servernum
.
@meuh가 지적했듯이 논리는사실 정말 쉬워요:
# Copyright (C) 2005 The T2 SDE Project
# Copyright (C) XXXX - 2005 Debian
# GNU GPLv2
find_free_servernum() {
# Sadly, the "local" keyword is not POSIX. Leave the next line commented in
# the hope Debian Policy eventually changes to allow it in /bin/sh scripts
# anyway.
#local i
i=$SERVERNUM
while [ -f /tmp/.X$i-lock ]; do
i=$(($i + 1))
done
echo $i
}
함수를 정의한 후 다음과 같이 호출해 볼 수 있습니다.사용하는 대신xvfb-run
:
Xvfb :$(find_free_servernum) -screen 0, 1024x768x16 firefox $1 &
THE_PID=$!
# kill Xvfb whenever you feel like it
kill -15 $THE_PID
제거 후 xvfb-run
: 더 이상 죽이는 방법에 대해 걱정할 필요가 없습니다 xvfb-run
.
답변2
오늘이 문제가 발생했습니다.
모두X 서버이 -terminate
주장을 지지하세요.
- 종료
계속하는 대신 서버 재설정 시 서버가 종료됩니다. 이는 이전 -noreset 명령줄 옵션을 재정의합니다.
xvfb-run
그래서 나는 's를 사용하여 이것을 지정 하게 되었습니다 -s
.
xvfb-run -d -s '-terminate' firefox --no-remote --profile $PROFILE_DIR $URL
따라서 Karma 테스트 실행기 예에서 Karma가 firefox 인스턴스를 종료하면 Xvfb 서버는 마지막 xclient(firefox)가 종료될 때 자체적으로 종료됩니다. xvfb-run은 Firefox가 종료된 후에도 실행을 완료합니다.
편집하다
나는 결국 xvfb-run 스크립트의 "간단한" 버전을 구성하게 되었습니다.
PROFILE=$(mktemp -d)
trap "rm -rf $PROFILE" EXIT
# Start Xvfb and let it find a display number itself.
# Some versions of Xvfb (apparently 1.17.x) refuse to write to stdout
Xvfb -displayfd 4 -terminate -nolisten tcp 4>$PROFILE/.Xdisplay &
# Wait a few seconds for Xvfb to start
sleep ${START_WAIT-2}
${FIREFOX_HOME}/firefox --profile $PROFILE --no-remote --display :$(<$PROFILE/.Xdisplay) "${@?}" &
# Karma appears to send a SIGTERM to the browser when it's done, forward that signal to the Firefox process.
trap "kill -SIGTERM $!" SIGTERM
# Wait for all children to terminate
wait
답변3
내 솔루션은 Docker 진입점 스크립트에서 xvfb를 시작하는 것이었습니다.
Xvfb :0 -screen 0 1024x768x24 &
.bashrc
Docker를 사용하지 않는 경우 일종의 OS 시작 스크립트(예:)에 동일한 줄을 넣을 수도 있습니다.
그런 다음 다른 스크립트에서 디스플레이를 내보내고 사용하려는 실제 함수를 호출합니다.
export DISPLAY=:0
firefox $1