如何终止交互式 shell 及其上运行的进程/作业?

问题描述 投票:0回答:2

我正在使用 docker 容器交互式 shell 在 shell 上执行命令。

e.g. docker exec -i docker_container_name sh

然后我在这个交互式 shell 上启动命令。现在,如果我想终止这个交互式 shell 和在其上运行的命令,该怎么做?

我尝试向交互式 shell 发送

kill -9 shell_pid or kill -s 15 shell_pid
信号。然而,在这种情况下,交互式 shell 被终止,但在交互式 shell 上运行的命令仍然存在,并成为孤儿进程。

请让我知道如何杀死运行在其上的命令的交互式 shell。

linux bash shell docker interactive
2个回答
1
投票

您应该先获取子进程,然后再杀死 shell 并杀死它们

CPIDS=`pgrep -P $shellpid` # gets pids of child processes
kill -9 $shellpid
for cpid in $CPIDS ; do kill -9 $cpid ; done

或者(这不太安全,因为,如果在 shell 中运行一系列命令,则可能会在这两个终止命令之间调用下一个命令)

pkill -TERM -P $shellpid # sends TERMINATE signal to children
kill -9 $shellpid

0
投票

对于 bash,最好使用的信号是

SIGHUP
。从docs,解释如下:

SIGHUP 默认退出 shell。交互式 shell 会向所有正在运行或已停止的作业发送 SIGHUP...


SIGHUP 的信号值为 1,因此您可以使用以下命令来结束交互式 bash shell:

kill -1 shell_pid

使用此方法,您不必去追踪 shell 的所有子进程,因为它会自行执行此操作。


此外,至于为什么使用 SIGKILL 或 SIGTERM 也没有终止子进程,同一文档对 SIGTERM 有解释:

在没有任何陷阱的情况下,交互式 Bash shell 会忽略 SIGTERMSIGQUITSIGINT 被捕获并处理,如果作业控制处于活动状态,SIGTTINSIGTTOUSIGTSTP 也会被忽略。当键盘生成时,作为命令替换结果运行的命令也会忽略这些信号。

最后,SIGKILL无法杀死子进程,因为SIGKILL信号对于任何接收到该信号的进程来说都是“致命的”。除了从进程表中 RIP 以及它生成的任何线程之外,无法以任何其他方式处理它。

© www.soinside.com 2019 - 2024. All rights reserved.