执行 xvfb-运行 作为 docker 自定义命令
Execute xvfb-run as docker custom command
为什么 xvfb-运行 不会作为 docker 覆盖命令执行?
从这个 Dockerfile 中获取图像:
FROM ubuntu:20.04
RUN apt-get update && apt-get install -y xvfb
构建于:
docker build -f Dockerfile.xvfb -t xvfb-test
如果我使用 xfvb-运行 执行自定义 docker 命令:
docker run xvfb-test bash -x /usr/bin/xvfb-run echo
卡住没完没了
但是,如果我进入图像 docker run --rm -it xvfb-test bash
,并执行相同的命令 xvfb-运行 echo 它会立即完成(意味着 Xvfb服务器已启动并能够执行命令)
这是 xvfb-运行 脚本的摘录:
...
trap : USR1
(trap '' USR1; exec Xvfb ":$SERVERNUM" $XVFBARGS $LISTENTCP -auth $AUTHFILE >>"$ERRORFILE" 2>&1) &
XVFBPID=$!
wait || :
...
用bash -x
执行我们可以看到最后执行的行是什么:
+ XAUTHORITY=/tmp/xvfb-run.YwmHlq/Xauthority
+ xauth source -
+ trap : USR1
+ XVFBPID=16
+ wait
+ trap '' USR1
+ exec Xvfb :99 -screen 0 1280x1024x24 -nolisten tcp -auth /tmp/xvfb-run.YwmHlq/Xauthority
查看 xvfb-run 脚本及其卡住的地方似乎是信号 USR1 (Xvfb 进程发送)永远不会传播到 wait 语句。
强制信号传播的一种方法是将 --init 标志添加到 docker 运行 命令。
来自documentation,正是它的作用。
Run an init inside the container that forwards signals and reaps processes
由此
The docker --init option in the run command basically sets ENTRYPOINT to tini and passes the CMD to it or whatever you specify on the commandline. Without init, CMD becomes pid 1. In this case, /bin/bash
看起来 运行 没有初始化参数的命令,运行 作为 PID 1,没有正确处理信号 USR1。
为什么 xvfb-运行 不会作为 docker 覆盖命令执行?
从这个 Dockerfile 中获取图像:
FROM ubuntu:20.04
RUN apt-get update && apt-get install -y xvfb
构建于:
docker build -f Dockerfile.xvfb -t xvfb-test
如果我使用 xfvb-运行 执行自定义 docker 命令:
docker run xvfb-test bash -x /usr/bin/xvfb-run echo
卡住没完没了
但是,如果我进入图像 docker run --rm -it xvfb-test bash
,并执行相同的命令 xvfb-运行 echo 它会立即完成(意味着 Xvfb服务器已启动并能够执行命令)
这是 xvfb-运行 脚本的摘录:
...
trap : USR1
(trap '' USR1; exec Xvfb ":$SERVERNUM" $XVFBARGS $LISTENTCP -auth $AUTHFILE >>"$ERRORFILE" 2>&1) &
XVFBPID=$!
wait || :
...
用bash -x
执行我们可以看到最后执行的行是什么:
+ XAUTHORITY=/tmp/xvfb-run.YwmHlq/Xauthority
+ xauth source -
+ trap : USR1
+ XVFBPID=16
+ wait
+ trap '' USR1
+ exec Xvfb :99 -screen 0 1280x1024x24 -nolisten tcp -auth /tmp/xvfb-run.YwmHlq/Xauthority
查看 xvfb-run 脚本及其卡住的地方似乎是信号 USR1 (Xvfb 进程发送)永远不会传播到 wait 语句。
强制信号传播的一种方法是将 --init 标志添加到 docker 运行 命令。 来自documentation,正是它的作用。
Run an init inside the container that forwards signals and reaps processes
由此
The docker --init option in the run command basically sets ENTRYPOINT to tini and passes the CMD to it or whatever you specify on the commandline. Without init, CMD becomes pid 1. In this case, /bin/bash
看起来 运行 没有初始化参数的命令,运行 作为 PID 1,没有正确处理信号 USR1。