在UNIX-y方式中,我试图启动一个进程,将其进行后台处理,并将该进程的生命周期与我的shell相联系。
我所说的不仅仅是后台进程的背景,我希望进程被发送SIGTERM,或者有一个打开的文件描述符被closures,或者当shell退出的时候,这样shell的用户不必明确杀死进程或得到“你有运行作业”的警告。
最终,我需要一个可以运行的程序,每个shell都可以独立运行,并随shell一起运行,并在shellclosures时closures。
IBM的DB2控制台命令以这种方式工作。 当连接到数据库时,它会产生一个“db2bp”进程,该进程携带数据库状态和连接并将其绑定到您的shell。 您可以连接多个不同的terminal或ssh连接,每个连接都有其自己的db2bp进程,当这些进程closures时,相应的db2bp进程将死亡,并且该连接将被closures。
DB2查询然后用db2命令启动,db2命令简单地把它移交给适当的db2bp进程。 我不知道它如何与正确的 db2bp进程通信,但也许它使用连接到标准input的tty设备作为唯一键? 我想我也需要弄清楚。
我从来没有写过任何tty操作,所以我不知道从哪里开始。 我想我可以找出其他的东西,如果我可以产生一个自动死在shell退出的进程。 任何人都知道DB2是如何做到的?
如果你的shell不是一个子shell,你可以执行以下操作; 把下面的脚本称为“ttywatch”:
#!/usr/bin/perl my $p=open(PI, "-|") || exec @ARGV; sleep 5 while(-t); kill 15,$p;
然后运行你的程序:
$ ttywatch commandline... & disown
放弃进程将防止shell抱怨有正在运行的进程,并且当终端关闭时,会在5秒内将SIGTERM( 15
)传递到子进程(你的应用程序)。
如果shell不是一个子shell,你可以使用像ttywrap这样的程序来至少给它自己的tty,然后上面的技巧就可以工作。
好吧,我觉得我明白了。 我让它太复杂:)
我认为所有的db2守护进程db2bp,然后db2bp调用父PID(shell的PID)waitpid,并在waitpid返回后退出。
db2命令和db2bp之间的通信似乎是通过fifo完成的,并且使用基于父shell PID的文件名。
Waaaay比我想象的更简单:)
对于任何一个好奇的人来说,这一切都是为了能够将一个python或groovy的交互式会话绑定到一个shell上,所以我可以测试代码,同时轻松地跳入和退出一个会保留数据库连接和临时类/变量的会话。
感谢大家的帮助!
关闭时,你的shell应该发送一个SIGHUP信号给正在运行的子进程。 你有没有尝试添加一个SIGHUP处理程序到你的应用程序,关闭干净的shell当退出?
这有可能是你真正的问题是壳而不是你的过程。 我的理解与吉姆·刘易斯(Jim Lewis)的观点相一致,那就是当贝壳去世的时候应该得到SIGHUP。 但是你抱怨的是shell(或者终端)试图阻止你意外地使用活动的子节点来杀死正在运行的shell。
考虑阅读shell或终端的手册,看看这个行为是否可配置。
从我的MacBook上的bash手册:
收到SIGHUP后,shell会默认退出。 在退出之前,交互式shell将SIGHUP重新发送到所有正在运行或停止的作业。 停止的工作发送SIGCONT,以确保他们收到SIGHUP。 为了防止shell将信号发送到特定的作业,应该使用disown内建函数(请参阅下面的SHELL BUILTIN COMMANDS)将其从作业表中删除,或者使用disown -h标记为不接收SIGHUP。
如果已经使用shopt设置了huponexit shell选项,则当交互式登录shell退出时,bash将向所有作业发送SIGHUP。
这可能会指向你正确的方向。