如果 运行 没有 shell,Ruby 退出,退出代码 1 响应 TERM
Ruby exits with exit code 1 responding to TERM if running without shell
如果Ruby接收到TERM信号,它通常以退出代码143退出,根据this source表示进程成功响应该信号。但是如果我使脚本 运行 没有 shell,退出代码是 1.
与shell:
> cat Dockerfile
FROM ruby:alpine
CMD ruby -e "Process.kill('TERM', Process.pid)" # <- shell form
> docker build -t term_shell . > /dev/null
> docker run term_shell
Terminated
> echo $?
143
没有shell:
> cat Dockerfile
FROM ruby:alpine
CMD ["ruby", "-e", "Process.kill('TERM', Process.pid)"] # <- exec form
> docker build -t term_exec . > /dev/null
> docker run term_exec
> echo $?
1
但是如果我用 143 退出,退出代码是预期的:
> cat Dockerfile
FROM ruby:alpine
CMD ["ruby", "-e", "exit(143)"] # <- exec form
> docker build -t exit_exec . > /dev/null
> docker run exit_exec
> echo $?
143
这是为什么? ruby 收到 TERM 时的退出代码是否来自 Ruby,而是 shell?
第二个示例的退出代码是 1
,因为调用 Process.kill('TERM', Process.pid)
失败。 ruby -e
因这次失败而退出,此时的状态码为 1
.
- 对于
CMD ruby -e "Process.kill('TERM', Process.pid)"
,docker在shell中执行给定的命令。在 运行 容器中,这意味着 pid 为 1 的根进程将是 /bin/sh -c
,而 ruby -e
命令将在具有另一个 pid(例如 6)的子进程中执行。
- 使用
CMD ["ruby", "-e", "Process.kill('TERM', Process.pid)"]
,docker直接执行ruby -e
作为根进程,pid 1。
Linux 上的 PID 1 行为与正常行为不同。来自 docker documentation:
Note: A process running as PID 1 inside a container is treated specially by Linux: it ignores any signal with the default action. So, the process will not terminate on SIGINT or SIGTERM unless it is coded to do so.
因此在您的情况下,TERM
信号不会发送给您的进程。
您可以在本文中找到有关 PID 1 行为的更多信息:
https://hackernoon.com/my-process-became-pid-1-and-now-signals-behave-strangely-b05c52cc551c
如果Ruby接收到TERM信号,它通常以退出代码143退出,根据this source表示进程成功响应该信号。但是如果我使脚本 运行 没有 shell,退出代码是 1.
与shell:
> cat Dockerfile
FROM ruby:alpine
CMD ruby -e "Process.kill('TERM', Process.pid)" # <- shell form
> docker build -t term_shell . > /dev/null
> docker run term_shell
Terminated
> echo $?
143
没有shell:
> cat Dockerfile
FROM ruby:alpine
CMD ["ruby", "-e", "Process.kill('TERM', Process.pid)"] # <- exec form
> docker build -t term_exec . > /dev/null
> docker run term_exec
> echo $?
1
但是如果我用 143 退出,退出代码是预期的:
> cat Dockerfile
FROM ruby:alpine
CMD ["ruby", "-e", "exit(143)"] # <- exec form
> docker build -t exit_exec . > /dev/null
> docker run exit_exec
> echo $?
143
这是为什么? ruby 收到 TERM 时的退出代码是否来自 Ruby,而是 shell?
第二个示例的退出代码是 1
,因为调用 Process.kill('TERM', Process.pid)
失败。 ruby -e
因这次失败而退出,此时的状态码为 1
.
- 对于
CMD ruby -e "Process.kill('TERM', Process.pid)"
,docker在shell中执行给定的命令。在 运行 容器中,这意味着 pid 为 1 的根进程将是/bin/sh -c
,而ruby -e
命令将在具有另一个 pid(例如 6)的子进程中执行。 - 使用
CMD ["ruby", "-e", "Process.kill('TERM', Process.pid)"]
,docker直接执行ruby -e
作为根进程,pid 1。
Linux 上的 PID 1 行为与正常行为不同。来自 docker documentation:
Note: A process running as PID 1 inside a container is treated specially by Linux: it ignores any signal with the default action. So, the process will not terminate on SIGINT or SIGTERM unless it is coded to do so.
因此在您的情况下,TERM
信号不会发送给您的进程。
您可以在本文中找到有关 PID 1 行为的更多信息: https://hackernoon.com/my-process-became-pid-1-and-now-signals-behave-strangely-b05c52cc551c