편집하다

편집하다

일부 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-run2012년에 버그 상태가 수정되었음에도 불구하고 여전히 유효한 것으로 보입니다 .

xvfb-run다른 프로세스를 올바르게 정리하기 위해 프로세스를 종료하는 정중한 방법이 있습니까 ?


이미 Stack Overflow에 문의했지만 지금까지 답변을 받지 못했습니다. 아마도 Stack Overflow의 경우 다소 구식이지만 여기에 위치하는 것이 더 좋습니다.

답변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: 더 이상 kill 방법에 대해 걱정할 필요가 없습니다 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

관련 정보