편집하다

편집하다

일부 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 &

.bashrcDocker를 사용하지 않는 경우 일종의 OS 시작 스크립트(예:)에 동일한 줄을 넣을 수도 있습니다.

그런 다음 다른 스크립트에서 디스플레이를 내보내고 사용하려는 실제 함수를 호출합니다.

export DISPLAY=:0
firefox $1

관련 정보