Chi*_*rag 20 linux shell telnet job-control
我有一个嵌入式系统,我在其上telnet
运行,然后在后台运行一个应用程序:
./app_name &
Run Code Online (Sandbox Code Playgroud)
现在如果我关闭我的终端并telnet
从其他终端做,如果我检查然后我可以看到这个过程仍在运行.
为了检查这个,我写了一个小程序:
#include<stdio.h>
main()
{
while(1);
}
Run Code Online (Sandbox Code Playgroud)
我在后台运行我的本地linux pc程序,然后我关闭了终端.
现在,当我从其他终端检查这个过程时,我发现这个过程也被杀死了.
我的问题是:
gav*_*avv 35
通常,前台和后台作业SIGHUP
在不同情况下由内核或shell发送.
SIGHUP
?内核发送SIGHUP
到控制进程:
内核发送SIGHUP
到其他进程组:
控制过程是建立与控制终端的连接的会话负责人.
通常,控制过程就是你的shell.所以,总结一下:
SIGHUP
当真实或伪终端断开/关闭时内核发送到shell;SIGHUP
shell终止时内核发送到前台进程组;SIGHUP
包含已停止的进程,则内核将发送给孤立进程组.请注意,如果内核不SIGHUP
包含已停止的进程,则它不会发送到后台进程组.
bash
发送SIGHUP
?Bash发送SIGHUP
到所有作业(前台和后台):
SIGHUP
,它是一个交互式shell(并且在编译时启用了作业控制支持);huponexit
设置了选项(并且在编译时启用了作业控制支持).在这里查看更多细节.
笔记:
bash
不会发送SIGHUP
到工作清单中删除的工作disown
;nohup
ignore SIGHUP
.更多细节在这里.
通常,shell会传播SIGHUP
.SIGHUP
在正常出口处生成不太常见.
在telnet或SSH下,连接关闭时会发生以下情况(例如,当您关闭telnet
PC上的窗口时):
SIGHUP
到bash
;bash
接收SIGHUP
,发送SIGHUP
到所有工作并终止;SIGHUP
并终止.我可以重现使用您的问题bash
,并telnetd
从busybox
或dropbear
SSH服务器:有时,后台作业不接收SIGHUP
(并且不终止),当客户端连接关闭.
当服务器(或)关闭pty的主端时,似乎发生了竞争条件:telnetd
dropbear
bash
接收SIGHUP
并立即杀死后台工作(如预期的那样)并终止;bash
检测EOF
pty的奴隶侧.SIGHUP
当bash
检测EOF
,默认情况下它会立即终止,不发送SIGHUP
.后台工作仍在运行!
也可以配置bash
为SIGHUP
正常退出(包括EOF
):
确保bash
以登录shell启动.该huponexit
作品只为登录shell,据我所知.
登录壳是由启用-l
选项,或导致连字符在argv[0]
.您可以配置telnetd
为在登录shell模式下运行/bin/bash -l
或更好地/bin/login
调用/bin/sh
.
例如:
telnetd -l /bin/login
启用huponexit
选项.
例如:
shopt -s huponexit
bash
每次在会话中键入此内容或将其添加到.bashrc
或/etc/profile
.
bash
仅在信号安全时解锁信号,并在信号处理程序无法安全中断某些代码段时阻止它们.
这些关键部分不时地调用中断点,并且如果在执行关键部分时接收到信号,则它的处理程序被延迟直到下一个中断点发生或退出临界区.
您可以从quit.h
源代码中开始挖掘.
因此,在我们的情况下,似乎bash
有时会SIGHUP
在关键部分接收.SIGHUP
处理程序执行被延迟,并在退出临界区或调用下一个中断点之前bash
读取EOF
和终止.
AFAIK 在这两种情况下都应该终止进程。为了避免这种情况,您必须发出如下所示的 nohup:
> nohup ./my_app &
Run Code Online (Sandbox Code Playgroud)
这样您的流程将继续执行。可能telnet部分是由于一个类似于这个的BUG:
https://bugzilla.redhat.com/show_bug.cgi?id=89653
当你关闭终端时,shell会发送SIGHUP
到所有后台进程 - 并且会杀死它们.这可以通过多种方式得到抑制,最值得注意的是:
当你运行程序时,nohup
它会捕获SIGHUP
并重定向程序输出.
$ nohup app &
Run Code Online (Sandbox Code Playgroud)
disown
告诉shell不发送 SIGHUP
$ app &
$ disown
Run Code Online (Sandbox Code Playgroud)
它取决于你的shell.以上至少适用于bash.