如何正确终止 xvfb-运行
Howto terminate xvfb-run properly
为了用 karma inside a docker container (based on ubuntu 14.04) I'm starting firefox in the container using a karma-script-launcher 和 xvfb-run
执行一些 JavaScript 单元测试。启动脚本如下所示:
#!/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
启动浏览器并执行单元测试效果很好。执行测试后,karma 终止生成的浏览器实例 - 在我的例子中是通过 xvfb-运行.
启动 firefox 的脚本
在上面的脚本中你可以看到我注册了一个 trap
来在我的脚本退出时终止启动的 firefox。这行得通,但是脚本不是一个很好的公民,因为它终止了当前 运行ning 的 all 个 firefox 实例,而不是仅仅终止由脚本。我首先尝试终止 xfvb-run
进程,但终止此进程对 xvfb-run
脚本启动的子进程没有影响...
如果我在 xvfb-run
上手动启动 firefox,则会出现一堆生成的进程:
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),只有这个进程会被终止,而其他进程 运行ning。如果我改为终止 firefox 进程 (PID 361),xvfb-run
脚本会正确终止并终止其他进程。但是从我的脚本中我只知道 xvfb-run
进程的 PID...
在我的研究过程中,我偶然发现了 this rather old bug report 的 xvfb-run
,尽管该错误的状态已在 2012 年修复,但它似乎仍然有效。
是否有礼貌的方式终止 xvfb-run
进程以便正确清理其他进程?
我前段时间在 unix.stackexchange.com 上发布了这个问题,因为它与 Unix/Linux 的关系比与一般编程的关系更大,因此在这里没有引起太多关注:
Howto terminate xvfb-run properly @ Unix & Linux
然而,正确终止 X 程序的唯一选择似乎是不使用 xvfb-运行 并编写您自己的脚本以使用 Xvfb 启动进程。
虽然年纪大了,但我最终还是遇到了这个。 dpr 的 post 中的 link 基本上是说要重新创建 xvfb-run 以便它可以更好地进行清理。因为我有一些空闲时间,所以我最后想看看是否可以避免这种情况。
我最终得到的是使用进程组。 xvfb-run 不会分离 Xvfb 或它在其下生成的命令,它仍然是同一 PGID 的一部分。对于 bash,这意味着 运行 处于监控模式,然后执行类似的操作(注意 PID 前的“-”):
xvfb-run -a blah &
xvfb_pid=$!
kill -- "-$xvfb_pid"
这将杀死 xvfb-run 领导的整个进程组。这仅适用于监控模式,因为只有监控模式才会为每个后台进程提供自己的组。
我不建议将作业控制功能与 bash 和脚本一起使用。我建议改为调用 setsid:
setsid xvfb-run -a blah &
xvfb_pid=$!
kill -- "-$xvfb_pid"
但是,请注意它调用 setsid 这也使子进程成为会话领导者。这比一个团体更强大,可能比我们想要的更多(虽然我想不出任何它会立即引起问题的东西)。
我最终使用了一个 C 解决方案,该解决方案在执行到 xvfb-run 之前在子进程中调用 setpgid(0,0)
而不是 setsid()
,并使用 killpg
终止进程。
为了用 karma inside a docker container (based on ubuntu 14.04) I'm starting firefox in the container using a karma-script-launcher 和 xvfb-run
执行一些 JavaScript 单元测试。启动脚本如下所示:
#!/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
启动浏览器并执行单元测试效果很好。执行测试后,karma 终止生成的浏览器实例 - 在我的例子中是通过 xvfb-运行.
启动 firefox 的脚本在上面的脚本中你可以看到我注册了一个 trap
来在我的脚本退出时终止启动的 firefox。这行得通,但是脚本不是一个很好的公民,因为它终止了当前 运行ning 的 all 个 firefox 实例,而不是仅仅终止由脚本。我首先尝试终止 xfvb-run
进程,但终止此进程对 xvfb-run
脚本启动的子进程没有影响...
如果我在 xvfb-run
上手动启动 firefox,则会出现一堆生成的进程:
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),只有这个进程会被终止,而其他进程 运行ning。如果我改为终止 firefox 进程 (PID 361),xvfb-run
脚本会正确终止并终止其他进程。但是从我的脚本中我只知道 xvfb-run
进程的 PID...
在我的研究过程中,我偶然发现了 this rather old bug report 的 xvfb-run
,尽管该错误的状态已在 2012 年修复,但它似乎仍然有效。
是否有礼貌的方式终止 xvfb-run
进程以便正确清理其他进程?
我前段时间在 unix.stackexchange.com 上发布了这个问题,因为它与 Unix/Linux 的关系比与一般编程的关系更大,因此在这里没有引起太多关注:
Howto terminate xvfb-run properly @ Unix & Linux
然而,正确终止 X 程序的唯一选择似乎是不使用 xvfb-运行 并编写您自己的脚本以使用 Xvfb 启动进程。
虽然年纪大了,但我最终还是遇到了这个。 dpr 的 post 中的 link 基本上是说要重新创建 xvfb-run 以便它可以更好地进行清理。因为我有一些空闲时间,所以我最后想看看是否可以避免这种情况。
我最终得到的是使用进程组。 xvfb-run 不会分离 Xvfb 或它在其下生成的命令,它仍然是同一 PGID 的一部分。对于 bash,这意味着 运行 处于监控模式,然后执行类似的操作(注意 PID 前的“-”):
xvfb-run -a blah &
xvfb_pid=$!
kill -- "-$xvfb_pid"
这将杀死 xvfb-run 领导的整个进程组。这仅适用于监控模式,因为只有监控模式才会为每个后台进程提供自己的组。
我不建议将作业控制功能与 bash 和脚本一起使用。我建议改为调用 setsid:
setsid xvfb-run -a blah &
xvfb_pid=$!
kill -- "-$xvfb_pid"
但是,请注意它调用 setsid 这也使子进程成为会话领导者。这比一个团体更强大,可能比我们想要的更多(虽然我想不出任何它会立即引起问题的东西)。
我最终使用了一个 C 解决方案,该解决方案在执行到 xvfb-run 之前在子进程中调用 setpgid(0,0)
而不是 setsid()
,并使用 killpg
终止进程。