Linux中的nohup,disown和&有什么区别?

职场十万个为什么


老胡的看法:

nohup,disown和&是Linux中用来进行作业控制的命令,它们都与作业的执行过程控制有关系。这三个家伙主要的区别在于对作业执行的调度动作上,区别还是很明显的。


一、先说说nohup

老胡打算先说nohup的主要原因是想说造成nohup、disown和&容易混淆的原因:HUP信号。Linux的shell在远程登录断开和用户登出时,会收到系统发送的HUP信号,然后就会陆续关闭它的子进程。无论我们是在本机的终端上登录的shell,还是远程登录的shell,在这个shell里面运行的所有命令都是它的子进程。如果在shell收到HUP的时候,我们不想自己运行的脚本或者命令被杀死,就需要用到nohup:

nohup 命令或脚本

这样一来,nohup后面的命令就会无视shell发来的HUP信号继续运行直到结束。

nohup会将紧随其后的命令或者脚本的标准输出重定向到

nohup.out

文件,一般我们使用它的时候都会将其重定向到自己定义的文件名:
nohup 命令或脚本 > filename 2>&1

通常我们使用nohup的时候,末尾都会加一个&一起使用。在上面的截图中可以看到,nohup后面的命令依然是当前shell的子进程。nohup不会将执行命令的作业与shell断开联系。


二、&都干了些什么

如果将一个命令后面加上&来执行,那么这条命令会被提交到作业列表,并且能够响应标准输入,命令的输出结果也能够输出到标准输出流和标准错误流:

使用jobs命令来查看作业列表可以看到这个任务的身影:

如果使用()将需要放置在后台执行的命令括起来的话,jobs就查不到这条作业了。

(ping &

原因是()以子shell进程运行,其父进程是系统进程init:

所以&与()配合使用,可以将命令作为init的子进程执行。


三、disown的作用

disown主要用于作业列表的控制它可以根据作业号,将指定的作业从作业列表中删除,并将作业进程转为init的子进程。

例如:

disown -h %1

就是将作业号为1的作业从作业列表中删除,在shell退出的时候将其作为init的子进程继续执行。

实际的应用中,比如我们在运行一条用时比较长的命令的时候,忽然临时需要登出系统或者关闭shell,而在当时运行这个命令时没有考虑到要提交为作业放到后台运行。可以先用Ctrl+z来挂起当前进程,使用jobs获得作业号,然后再使用disown来切断这个命令与当前shell进程的联系,这样就可以避免shell关闭的时候会中断命令的执行。


总结一下,nohup,disown和&之间的区别可以用作业调度的能力来看,排序如下:

disown>&>nohup。nohup只能让命令在执行时忽略shell传来的HUP信号,使命令能够无视shell的退出继续执行完毕;disown可以随意调度正在执行的作业,使之与shell断开联系从而避免被HUP信号终止;&配合()进行子shell调用可以实现将命令作为init的子进程执行。


如果我的回答对你有点价值,请莫忘点赞加关注,谢谢!欢迎在评论区发表各种意见。

本文为作者原创,严禁转载,违者必究。


分享到:


相關文章: