两者有什么区别
$ nohup foo
和
$ foo &
和
$ foo &
$ disown
答案1
让我们首先看看如果从交互式 shell(连接到终端)启动程序而没有&
(并且没有任何重定向)会发生什么。所以我们假设您刚刚输入foo
:
- 正在运行的进程
foo
已创建。 - 该进程从 shell 继承 stdin、stdout 和 stderr。因此它也连接到同一终端。
- 如果 shell 收到 a
SIGHUP
,它还会SIGHUP
向进程发送 a (这通常会导致进程终止)。 - 否则,shell 将等待(被阻止),直到进程终止或停止。
现在,让我们看看如果将进程放在后台会发生什么,即输入foo &
:
- 正在运行的进程
foo
已创建。 - 该进程从 shell 继承 stdout/stderr (因此它仍然写入终端)。
- 该进程原则上也继承了 stdin,但一旦它尝试从 stdin 读取,它就会停止。
- 它被放入 shell 管理的后台作业列表中,这尤其意味着:
- 它列出
jobs
并可以使用%n
(其中n
是作业编号)进行访问。 - 可以使用将其转换为前台作业
fg
,在这种情况下,它会继续,就像您不会使用&
它一样(如果它由于尝试从标准输入读取而停止,那么它现在可以继续从终端读取)。 - 如果 shell 收到一个
SIGHUP
,它也会SIGHUP
向进程发送一个 。根据 shell 以及可能为 shell 设置的选项,当终止 shell 时,它也会SIGHUP
向进程发送 a 。
- 它列出
现在disown
从 shell 的作业列表中删除该作业,因此上面的所有子点不再适用(包括SIGHUP
shell 发送的进程)。但请注意,它仍然连接到终端,因此如果终端被破坏(如果它是一个 pty,则可能发生这种情况,如由xterm
或创建的 pty ssh
,并且控制程序通过关闭 xterm 或终止SSH连接),程序一旦尝试从标准输入读取或写入标准输出就会失败。
另一方面nohup
,有效地将进程与终端分开:
- 它关闭标准输入(程序将不是能够读取任何输入,即使它在前台运行。它不会停止,但会收到错误代码或
EOF
)。 - 它将标准输出和标准错误重定向到文件
nohup.out
,因此如果终端出现故障,程序不会因写入标准输出而失败,因此进程写入的任何内容都不会丢失。 - 它阻止进程接收 a
SIGHUP
(因此得名)。
请注意,确实nohup
如此不是从 shell 的作业控制中删除该进程,并且也不将其放入后台(但由于前台nohup
作业或多或少是无用的,因此您通常会使用 将其放入后台&
)。例如,与 with 不同disown
,shell 仍会告诉您 nohup 作业何时完成(当然,除非 shell 之前已终止)。
总结一下:
&
将作业置于后台,也就是说,使其在尝试读取输入时被阻止,并使 shell 不等待其完成。disown
将进程从 shell 的作业控制中删除,但仍保持与终端的连接。结果之一是 shell 不会向其发送SIGHUP
.显然,它只能应用于后台作业,因为当前台作业运行时你无法输入它。nohup
断开进程与终端的连接,将其输出重定向到nohup.out
并屏蔽它SIGHUP
。影响之一(命名的影响)是进程不会接收任何发送的SIGHUP
.它完全独立于作业控制,原则上也可以用于前台作业(尽管这不是很有用)。
答案2
使用&
会使程序在后台运行,因此您将得到一个新的 shell 提示符,而不是阻塞直到程序结束。nohup
并且disown
基本上不相关;它们抑制 SIGHUP(挂断)信号,因此当控制终端关闭时程序不会自动终止。nohup
当工作第一次开始时执行此操作。如果您nohup
在作业开始时没有启动,您可以使用disown
修改正在运行的作业;没有任何参数,它会修改当前的作业,即刚刚后台运行的作业
答案3
这是我尝试在后台运行 soffice 的经验,遵循非终止命令(例如tail
)。对于这个例子,我将使用sleep 100
.
在下面的所有情况下,我都是这样执行的:
./scriptfile
<Ctl-C>
&
#!/bin/bash
/opt/libreoffice4.4/program/soffice -invisible -nofirststartwizard &
sleep 100
我看办公室日志/ 按Ctrl-C办公站
诺哈普..&
#!/bin/bash
nohup /opt/libreoffice4.4/program/soffice -invisible -nofirststartwizard &
sleep 100
我没看到办公室日志/ 按Ctrl- Csoffice 停止
& 否认
#!/bin/bash
/opt/libreoffice4.4/program/soffice -invisible -nofirststartwizard & disown
sleep 100
我看办公室日志/ 按Ctrl-C办公站
集西德..&
#!/bin/bash
setsid /opt/libreoffice4.4/program/soffice -invisible -nofirststartwizard &
sleep 100
我看办公室日志/ 按Ctrl- Csoffice不停歇
为了节省空间::
nohup setsid ..
不显示日志/soffice不会停止Ctrl-C
nohup
结尾处& disown
:不显示日志/办公室停止于Ctrl-C
答案4
另请参阅daemonize
(1) 实用程序,它处理有关运行“真正后台”进程的所有杂务。根据其文档:
daemonize 作为 Unix 守护进程运行命令。正如 W. Richard Stevens 在 1990 年出版的《Unix 网络编程》一书中所定义的那样(Addison-Wesley,1990),守护进程是“一个在后台执行的进程(即,没有关联的终端或登录 shell),或者等待某个进程”。事件发生,或等待定期执行某些指定的任务。”启动时,典型的守护程序将:
- 关闭所有打开的文件描述符(特别是标准输入、标准输出和标准错误)
- 将其工作目录更改为根文件系统,以确保它不会占用另一个文件系统并防止其被卸载
- 重置其 umask 值
- 在后台运行(即fork)
- 与其进程组(通常是 shell)解除关联,以将自身与发送到进程组的信号(例如 HUP)隔离
- 忽略所有终端 I/O 信号
- 与控制终端断开连接(并采取措施不再重新获取控制终端)
- 处理任何 SIGCLD 信号
大多数设计为作为守护进程运行的程序都可以自行工作。但是,您偶尔会遇到不这样做的情况。当您必须运行一个无法正确地将自己变成真正的 Unix 守护程序的守护程序时,您可以使用 daemonize 强制它作为真正的守护程序运行。
它取代了所有的&
//混乱。nohup
disown