linux - 在 BASHRC 与命令行中启动后台进程之间的区别
问题描述
我正在尝试自动后台处理进程。
nohup program > /tmp/program.log 2>&1 < /dev/null &
disown
如果我检查进程是否正在运行并在登录时通过“.bashrc”启动它,程序会启动,但当我退出时会死机。
但是,如果我在命令行上执行完全相同的命令,当我退出时,程序会继续在后台运行。
我在 bashrc 启动和 cli 启动之间的程序环境中找不到任何区别。(bashrc 中几乎没有任何内容)。我对这两种情况下的程序的理解应该被同等对待。
有什么区别,当 shell 退出时,如何阻止 bashrc 启动的“守护进程”被杀死。
PS:删除 nohup 没有区别。当开始登录退出时,我已经看到程序运行然后从单独的登录中死亡。
在有人说什么之前......在 bashrc 中为程序设置背景后添加“拒绝”并没有解决它!
更新:如果 ssh 登录连接被终止(窗口关闭或连接突然终止),则在 bashrc 中启动的程序继续运行,但这似乎是因为启动它的 bash 也仍在运行(至少暂时如此) . 仅当您为 bash 键入“exit”或 bash 被杀死(即使使用不可捕获的信号 9!)时,背景才会被杀死。
程序的 PPID(被 shell 拒绝)是 0,即它的父进程不是 shell 也不是 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
现在,当 shell 存在时,程序不会退出。所以看起来唯一不同的是PGID改变了。
如何在不同的 PGID 中启动进程?
解决方案
作业控制需要进程组,因为 shell 需要一些东西来发送作业控制信号,例如当您键入fg
. POSIX.1-2017状态
支持作业控制的命令解释器进程可以将终端分配给不同的作业或进程组,方法是将相关进程放置在单个进程组中并将该进程组与终端相关联
(斜体是我的)这似乎甚至等同于“进程组”和“作业”的概念,尽管大多数人使用术语“作业”来表示在贝壳作业表(并且可以通过内置从该表中删除disown
)
因此,如果 shell 不想在作业控制下启动子命令(甚至 shell 管道),它不会创建新的进程组(通过调用setpgrp()
)
例如,在使用进程替换时会发生这种情况
blah=$(sleep 1000 | sleep 1000)
(试试看,看看ps -jA w
!)的输出,显然,当从.bashrc
nohup <command>
,它本身不会启动一个新的进程组,它只会忽略 SIGHUP
然后执行command
Linux(和其他操作系统,当您安装类似的东西时util-linux
)有一个命令setsid将执行您期望 (但没有得到)的操作nohup
: setsid command
将为新进程组创建一个新进程组并<command>
使其成为新会话的会话领导者。调用者(在这种情况下)PGID
将不知道这个新进程组的 ,bash
因此我们不再需要使用nohup
。
所以,使用setsid
代替,nohup
你就完成了(我现在才看到 Mark Plotnick 的评论,这对钱是正确的。哦,我希望我的回答也澄清了为什么在setsid
这种情况下是更好的选择)
推荐阅读
- javascript - 使用 Javascript 和单选按钮显示文本文件
- javascript - 在段落标记内插入选定文本的 HTML 标记
- ruby-on-rails - 共享点提供商在 Visual Studio 2017 中托管应用程序以在组织级别发布
- java - Spring RequestMapping 不会在 .jsp 请求上触发
- ios - 在使用 swift 的 iOS 中,如何创建一个始终位于整个应用程序顶部的可拖动和浮动 UIView
- python - Jupyter notebook 多窗口输出
- ios - 用动画在 UIImageView 上显示多个图像
- android - Android:使用 webview 捕获图像
- android - 使用滑行从 gif 图像中删除透明的白色背景?
- firebase - Firebase 规则不起作用。即使我在 Firestore 中设置规则也返回数据