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;SIGHUPshell终止时内核发送到前台进程组;SIGHUP包含已停止的进程,则内核将发送给孤立进程组.请注意,如果内核不SIGHUP包含已停止的进程,则它不会发送到后台进程组.
bash发送SIGHUP?Bash发送SIGHUP到所有作业(前台和后台):
SIGHUP,它是一个交互式shell(并且在编译时启用了作业控制支持);huponexit设置了选项(并且在编译时启用了作业控制支持).在这里查看更多细节.
笔记:
bash 不会发送SIGHUP到工作清单中删除的工作disown;nohup ignore SIGHUP.更多细节在这里.
通常,shell会传播SIGHUP.SIGHUP在正常出口处生成不太常见.
在telnet或SSH下,连接关闭时会发生以下情况(例如,当您关闭telnetPC上的窗口时):
SIGHUP到bash;bash接收SIGHUP,发送SIGHUP到所有工作并终止;SIGHUP并终止.我可以重现使用您的问题bash,并telnetd从busybox或dropbearSSH服务器:有时,后台作业不接收SIGHUP(并且不终止),当客户端连接关闭.
当服务器(或)关闭pty的主端时,似乎发生了竞争条件:telnetddropbear
bash接收SIGHUP并立即杀死后台工作(如预期的那样)并终止;bash检测EOFpty的奴隶侧.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.