脚本:disown,&和nohup的区别

Posted afatgoat

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了脚本:disown,&和nohup的区别相关的知识,希望对你有一定的参考价值。

disown,&和nohup的区别


注:前几天看到的在stackexchange上的文章(https://unix.stackexchange.com/questions/3886
/ difference-between-nohup-disown-and),现意译如下.


首先,先来看看一个普通的进程/程序在交互Shell中是如何被执行的,假设我们运行foo程序:


foo进程被生成,该进程继承了Shell中的stdin, stdout和stderr,所以foo被连接到了这个Shell终端;
如果Shell接受到了SIGHUP信号(这个信号一般用来终止进程),Shell会将这个信号发送给它下面的所有进程,
直到所有进程都结束,才退出。


现在看看将进程至于后台的情况,也就是运行: foo &


foo进程被生成,该进程继承了Shell中的stdout和stderr,所以foo的输出被连接到了这个Shell终端;理论
上foo的stdin也从Shell继承,但是只要它以读取stdin,就会挂起,因为无法从stdin读取。因为&,foo进程
被至于后台,由jobs命令可以查看到,可使用%n(n是后台进程的进程号)。使用fg命令将它再次至于前台,如果
它从前因试图从stdin读取而被挂起,那么前台后,它可以继续从stdin读取数据了。
如果Shell接受到了SIGHUP信号,Shell会将这个信号发送给它下面的所有进程,包括后台,直到所有进程都结
束,才退出。

如果使用disown命令将进程从jobs列表中移除了,那么上面的都不再适用。但是注意它始终连接到启动它的Shell
所以,原Shell终止后,只要disown的进程对任何stdin,stdout或stderr操作,就会产生错误。

再看看nohup foo:


它会会将foo的stdin关闭,也就是说foo无法从stdin读数据,即便是再次从后台唤醒到前台;然后将foo进程的
stdou和stderr重定向到nohup.out文件,所以foo进程不会因输出而产生错误;同时它还防止foo进程接受
Shell的SIGHUP信号。但是注意nohup不会将进程从Shell的jobs列表中移除,并且并不将其防止后台(当然
一般配合nohup使用都会与&联合使用置其后台)

总结来说:
&: 将进程置于后台,使Shell不用等待它的结束而继续接受用户输入(stdin)。
disown: 将进程从jobs列表中移除, 但依然与Shell有连接
nohup: 将进程与父Shell完全脱离,且子进程不会接受NOHUP信号,并不能用fg或者jobs命令找到它。

所以,要使子进程完全脱离Shell的命令是:
nohup foo </dev/null >/dev/null 2>&1 &

以上是关于脚本:disown,&和nohup的区别的主要内容,如果未能解决你的问题,请参考以下文章

[Linux内核]ctrl-z/fg/bg/nohup/setsid/()与&/disown/screen

Linux--命令--部署

disown 忽略hup信号,使后台运行

nohup和&的区别

nohup和&的区别

nohup和&的区别