Answers:
守护进程的传统方式是:
fork()
setsid()
close(0) /* and /dev/null as fd 0, 1 and 2 */
close(1)
close(2)
fork()
这样可以确保该进程不再与终端在同一个进程组中,因此不会被杀死。IO重定向是为了使输出不出现在终端上。
&
您的答案中添加零件说明。它似乎不完整..如果您检查原始问题。
对于守护程序,您想要的是一个与任何事物都没有关系的进程。至少,您希望它位于自己的会话中,不附加到终端,不希望从父对象继承的任何文件描述符对任何对象都开放,不希望父对象(除init之外)拥有当前对象目录中/
以免造成不必要的负担...
要与终端分离,请创建一个新会话,但是,要创建会话,您不能成为组(或会话)的领导者,因此最好是派生一个新进程。假设父级退出,这也意味着该进程将不再具有父级,并且将被init所采用。然后,关闭所有可能的文件描述符,您chdir("/")
(一个人无法像文件描述符一样关闭当前工作目录以释放该资源,使/
当前工作目录至少不会阻止卸载目录)。
由于该过程是会话的领导者,因此如果打开终端设备,就有可能成为该终端的控制过程。第二次分叉确保它不会发生。
另一方面,&在交互式外壳程序中派生并创建一个新的进程组(以使其不在终端的前台进程组中),而在非交互式外壳程序中,派生一个进程并忽略其中的SIGINT。它不会与终端分离,也不会关闭文件描述符(尽管某些shell会将stdin重新打开为/dev/null
)...
将程序/进程作为守护程序运行,并使用与号将其分叉到后台,这之间的区别基本上与所有权有关。
通常,守护进程的父进程是init进程(第一个在Unix系统上启动的进程),该守护进程是该进程的子进程,这意味着该进程不受您作为非特权用户的直接控制。 。另一方面,将程序/进程派生到后台意味着您可以随时将其调用回前台和/或杀死它。
随着command &
当父母去世你的过程将得到一个SIGHUP信号被杀死。
不过,系统管理员可以访问某些解决方法。
在bash系统上,您可以使用:
(trap '' HUP; command) &
这将打开一个子外壳,HUP
用一个空的处理程序捕获信号并用“与”号分叉。
输出可能仍会重定向到错误的位置tty
。否则迷路。
您可以修复与&>command.out
,1>output.out
或2>errors.out
在大多数系统上,您也可以访问该nohup
命令。
nohup
大大简化了此过程。这是很标准的,但是我发现许多busybox嵌入式ARM发行版都缺少它。您只需写:
nohup command &
..您就完成了。输出将IIRC重定向到nohup.out
,但是可以使用选项更改此文件名。
command &
以后的版本与Shell 分离disown
,然后再将其用作no -hup。