在BASHRC与命令行中启动背景过程之间的区别



我正在尝试自动背景过程。

nohup program > /tmp/program.log 2>&1 < /dev/null &
disown

如果我检查该过程是否正在运行并通过" .bashrc"在登录时启动,则该程序启动,然后在我退出时死亡。

但是,如果我在命令行上进行完全相同的命令,则程序将继续在后台运行。

我找不到BASHRC启动和CLI启动之间的程序环境的任何区别。(BashRC几乎没有(。在这两种情况下,我的理解都应相同。

有什么区别,我该如何停止Bashrc开始"守护程序",当炮弹退出时被杀死。

ps:删除NOHUP没有区别。我已经观看了程序运行,然后在开始登录时从单独的登录中垂死。

在有人说任何内容之前...在BashRC中背景程序后添加" disown"没有修复!

更新: 如果SSH登录连接被杀死(窗口关闭或突然终止(程序开始在BashRC中开始运行,但这似乎是因为启动的bash也仍在运行(至少暂时存在(。仅当您输入"退出"以进行bash或bash被杀死时,背景才会被杀死(即使有无法受伤的信号9!(。

程序的PPID(由外壳拒绝(是其父级的0不是壳,也不是Init进程!无论是如何开始的情况。

更新2 ...背景程序从bashrc ...

开始
# ps -jA w
   PID   PGID    SID TTY      STAT   TIME COMMAND
   891    891    891 pts/2    Ss+    0:00 /bin/bash
   899    891    891 pts/2    Sl+    0:00 program

我杀死了那个然后从命令行开始...

   891    891    891 pts/2    Ss+    0:00 /bin/bash
   958    955    891 pts/2    Sl     0:00 program

现在,当外壳存在时,程序不会退出。因此,看起来唯一不同的是PGID更改。

如何在其他PGID中开始一个过程?

工作组需要进程组,因为壳需要一些东西将作业控制信号发送到例如当您键入fg时。POSIX.1-2017状态

命令解释器流程支持工作控制可以通过将相关过程放置在单个过程组中,并将此过程组与终端

相关联,可以将终端分配给不同的作业或过程组

(斜体是我的(,这甚至似乎等同于"过程组"one_answers"工作"的概念,尽管大多数人都将术语用于过程组(甚至是外壳自己的过程组中的孩子(在shells 作业表中注册

因此,如果外壳不想在工作控制下启动子命令(甚至是壳管道(,则不会创建新的进程组(通过调用setpgrp()(

这发生了,例如使用过程替代

blah=$(sleep 1000 | sleep 1000)

(尝试一下,并查看ps -jA w的输出!(,显然,从.bashrc

启动命令时

nohup <command>本身不会启动一个新的进程组,它只忽略SIGHUP,然后执行command

linux(安装诸如util-linux之类的内容时(具有一个命令setSID,它将完成您预期的(但未得到的(nohupsetsid command:CC_11将为<command>创建一个新的进程组,并将其作为会话使其成为会话新会议的负责人。该新过程组的PGID将是呼叫者未知的(在这种情况下为bash(,因此我们不需要再使用nohup

所以,请使用setsid代替nohup,您已经完成了(我现在只看到Mark Plotnick的评论,这是正确的。哦,我希望我的答案也澄清了原因为什么在这种情况下,setsid是更好的选择(

好吧...似乎问题实际上是由环境引起的。

外壳正在码头容器中运行。看来Docker Exec是终止同一过程组中的所有进程的一个,而不是Shell。或至少似乎是这种情况。

但是,我仍然觉得很奇怪的是,从" .bashrc"中的程序继承了与父壳相同的进程组,但是从命令行中完全相同的背景命令获得了自己的单独进程组。

一旦我发现这是原因,我在bash manpage中提到了过程组,但在背景过程中,尽管没有提及在" .bashrc" vs cli中启动它的差异。

每个bash过程都有一个PPID(父pid(

如果从终端运行以下内容:

nohup tail -f /dev/null > /tmp/rand.txt &

ps -ef输出的PPID显示PPID是INIT(第一个开始的过程(:

UID        PID  PPID  C STIME TTY          TIME CMD
user     18424     1  0 16:17 tty1     00:00:00 tail -f /dev/null

如果您从bashrc运行相同的命令,则ppid是bash过程:

UID        PID  PPID  C STIME TTY          TIME CMD
user     16405 16404  0 Jun20 tty2     00:00:08 bash
user     18424 18386  0 16:17 tty1     00:00:00 tail -f /dev/null

从终端运行时,过程将继续直到停止。

从BashRC跑步时,该过程将继续直到停止BASH。

最新更新