IT博客汇
  • 首页
  • 精华
  • 技术
  • 设计
  • 资讯
  • 扯淡
  • 权利声明
  • 登录 注册

    [译]脚本:disown,&和nohup的区别

    afatgoat发表于 2017-05-16 06:16:41
    love 0
    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 &


沪ICP备19023445号-2号
友情链接