我们使用 Linux 系统工作,有时候可能会退出终端(注销会话),比如重新登录,切换其他工作,或者晚上下班等等。而有些程序,我们希望在退出终端后能继续工作,比如数据库,ssh服务等。然而,如果我们使用命令行启动的这些程序,在默认情况下,退出终端,服务也会被停止。使用 nohup,可以让我们在退出终端后,让程序/进程/命令可以继续运行。
nohup 表示 no hang up(不挂断),这是一个非常有用的命令,可以让进程在注销会话后仍能运行。
一个很常见的用法之一,就是通过 ssh 连接到服务器,由于网络等限制因素,有可能会让 ssh 连接中断,所以使用 nohup 让命令能不受会话中断的影响而继续运行:
nohup <command> &
nohup 命令是什么?
nohup 可以认为是一个包装器,在命令前面加上 nohup,它的语法结构如下所示:
nohup <command> [ARGS]
nohup 的目的是拦截并阻止 SIGHUP 信号接触命令。在命令前面加上 nohup 时,输入将从不可读的文件重定向(nohup COMMAND </dev/null),简单来说,就是如果使用了nohup,那么命令需要在无人值守的情况下运行;相反如果需要向命令输入参数,请不要使用 nohup。
提示:nohup 默认会将输出发送到 ./nohup.out 或者 ~/nohup.out 文件中,你可以给一个文件地址作为参数让输出重定向到指定的文件中:
nohup <COMMANDS> >/path/to/output/file
此外,nohup 没有什么参数,除了 --help 和 --version。
一些使用 nohup 的例子
使用 nohup 执行脚本,可参照如下例子:
nohup ./nhp.sh

请注意,nohup 没有将进程转移到后台,它只是拦截 SIGHUP 信号。命令运行后,当你关闭终端的时候,会弹出一个警告,告诉你有进程正在运行,你可以根据需要选择确定关闭。

当关闭终端时,所有的子进程都会收到一个 SIGHUP 信号,但是使用 nohup 的命令除外,因为 nohup 阻止了该信号。如下图所示终端关闭前关于nhp脚本的运行信息:

注意图中显示的 PPID,这是父进程ID。当关闭终端的时候,PPID的所有子进程都收到了 SIGHUP 信号(nohup命令除外)。然后父进程终止,使用 nohup 的nhp脚本成为了孤立进程。当一个进程被孤立时,它会自动将 assign 1(systemd 或者 init)作为父进程,如下图,再次打开终端时关于nhp的运行信息:

nohup 的使用非常简单,可以使用 & 符号,将进程发送到后台,如下所示:
nohup ./nhp.sh &
同时还可以指定输出信息到指定的文件:
nohup ./nhp.sh >/path/to/file &
注意:如果关闭或者重启 Linux 系统,所有的命令都会被终止,nohup 命令也不例外。当关闭或重启系统时,所有的进程都会收到 SIGTERM,然后是 SIGKILL。nohup不会拦截这些信号。
通过 ssh 连接的 nohup
使用 nohup 时,经常想到的一个场景时通过 ssh 在远程计算机上启动进程。从逻辑上讲,使用 nohup,从 ssh 注销连接后,进程可以继续运行。
nohup COMMAND &
一个常见的问题是,有时候 ssh 会在注销时挂起(hang),这是因为 ssh 通常不会主动丢失与任何后台进程之间的数据流,所以会挂起,直到进程终止。
这个问题通常可以通过重定向所有3个数据流来解决:
nohup COMMAND >./nohup.out 2>./nohup.err &
以上就是本次分享全部内容,欢迎讨论。




