nohup和守护进程有什么区别?

将脚本作为守护进程运行而不使用nohup有什么意义?

我知道在分叉过程等方面有什么不同,但是这对我的脚本有什么影响?

nohup命令是穷人以守护进程运行进程的方式。 正如Bruno Ranschaert指出的那样,当您在交互式shell中运行一个命令时,它有一个控制terminal,当控制进程(通常是您的loginshell)退出时将收到SIGHUP(挂断)信号。 nohup命令安排来自/dev/nullinput,并将输出和错误都转到nohup.out ,程序忽略中断,退出信号和挂断。 它实际上仍然有相同的控制terminal – 它只是忽略了terminal控制。 请注意,如果您希望进程在后台运行,则必须告诉shell在后台运行它 – 至less在Solaris上(即,键入' nohup sleep 20 & ';没有&符号,进程运行同步在前台)。

典型地,通过nohup运行的进程需要时间,但是并不等待来自其他地方的交互。

通常情况下(这意味着如果你努力工作,你可以find这些规则的例外),守护进程是潜伏在后台,从任何terminal断开,但等待某种input的响应。 networking守护进程等待连接请求或UDP消息通过networking到达,执行适当的工作并再次发回响应。 想想一个Web服务器,或者一个DBMS。

当一个进程完全守护自己时,它经历了nohup代码所经历的一些步骤; 它重新安排了它的I / O,所以它没有连接到任何terminal,从过程组中分离出来,忽略了合适的信号(这可能意味着它不会忽略任何信号,因为没有terminal发送任何产生的信号通过terminal)。 通常情况下,它分叉一次,父母成功退出。 subprocess通常在修复进程组和会话ID之后再次分叉; 孩子也退出。 孙子过程现在是自主的,并不会出现在启动terminal的ps输出中。

您可以参考Unix环境下的高级编程, W Richard Stevens和Stephen A Rago撰写的第三版,或Marc J Rochkind的第二版“高级Unix编程”中关于守护进程的讨论。

我有一个程序daemonize将守护程序不知道如何守护自己(正确)。 这本书是为了解决一个本来应该自我牺牲的程序中的缺陷,但没有正确地做好这个工作。 联系我,如果你想要的 – 见我的个人资料。

成为守护进程

这个链接有一个过程应该成为守护进程的一个很好的步骤列表: http : //www.steve.org.uk/Reference/Unix/faq_2.html#SEC16

我不能因为版权而逐字复制列表(参见关于部分),但是这里是总结:

  1. fork (第一次) – 所以我们不是组长,并让父母退出。
  2. 调用setsid() – 成为新会话的领导者。 这个电话只有在我们不是小组组长的情况下才有效。 这个新的会议没有控制terminal。
  3. fork (第二次) – 所以我们不是会议的领导者(因此不能重新获得控制terminal),并让父母退出。
  4. cd到根目录 – 所以我们不阻止其他目录被卸载。
  5. umask设置为期望值(可选) – 因为我们可以inheritance我们不想要的掩码。
  6. closures标准input,标准输出,标准错误(或只是重新打开它们指向其他地方)

nohup的

什么nohup做:

  • 如果stdout和stderr连接到terminal,则将其redirect到nohup.out
  • 忽略SIGHUP

共同点和不同点

注意唯一的常见操作是redirectstdout和stderr。 成为守护进程甚至不需要忽略SIGHUP。

nohup不要求你使用' & '作为后台进程的后台 – 这意味着你仍然可以使用ctrl-c发送SIGINT。 该过程仍然响应键盘input。 它也不会自动更改stdin,因此build议您通过“ < /dev/null ”自己执行。

请不要混淆nohup与通常使用它的其他function(如背景)。 OP特意询问nohup

在实践中

在实用性方面,当你想要开始一个长时间运行的过程,而这个过程在shell离开的时候应该会继续下去,你可以使用nohup ,但是你也想把它和stdin的后台和redirect结合起来。 一次性工作不值得做一个守护进程,但守护进程的一些属性仍然可以用nohup工作,比如“ cd / ”。

定期执行的定期任务最好通过cron (或其他调度程序)运行。

守护进程最适合监督没有可预测的开始时间的重复任务。 守护进程通常没有确定的结束时间(由用户/另一个进程或系统closures明确停止)。 守护进程通常是响应应用程序(客户端)或其他条件(例如通过unix select()在IO设备上传入数据)的服务。 其他守护进程轮询一个条件并执行一个响应的操作。

有关控制terminal的增编

看到这个页面 。 一个简短的总结是,控制terminal授予无限制的访问其标准input,标准输出,标准错误。 只有一个进程组可以访问标准input。 默认情况下,后台进程组也可以写入标准输出和标准错误。

而且,发送到terminal的键盘信号似乎只被发送到具有它作为控制terminal的处理组。

在UNIX变体中,进程与terminal进程(loginshell)相关联。 所以当terminal进程退出时,由于这种关联,进程也停止了。 nohup在terminal停止时阻止进程退出。

守护进程或恶魔是启动时由系统启动的一个进程,它运行到closures,没有用户明确要求。 所以根据定义,它不是用户交互的一部分,而是属于系统。

如果您以用户身份访问系统,则可以使用nohup。 如果你是系统pipe理员,你可以安装一个deamon进程。 对于这个过程并不重要。

守护进程不能启动,而nohup是由用户启动的。