vlambda博客
学习文章列表

[Linux笔记] nohup 命令 解决 SSH关闭窗口,程序也中断的问题!

今天在阿里云服务部署IOT测试软件,

发现关闭SHH窗口,IOT程序也退出了。


[Linux笔记] nohup 命令 解决 SSH关闭窗口,程序也中断的问题!

[Linux笔记] nohup 命令 解决 SSH关闭窗口,程序也中断的问题!

查了半天资料,发现通过nohup指令能解决该问题。


以下是网上查找的资料,供自己查看。


问题描述

  • 当SSH远程连接到服务器上,然后运行一个程序,eg: ./test.sh, 然后把终端开闭(切断SSH连接)之后,发现该程序中断.


原因

  • 主要元凶: 挂断信号(SIGHUP) 信号

概念介绍

  • 在Linux/Unix中,有这样几个概念:

  • 进程组(process group): 一个或多个进程的集合,每一个进程组有唯一一个进程组ID,即进程组长进程的ID.

  • 会话期(session): 一个或多个进程组的集合,有唯一一个会话期首进程(session leader). 会话期ID为首进程的ID.

  • 会话期可以有一个单独的控制终端(controlling terminal).

  • 与控制终端连接的会话期首进程叫做控制进程(controlling process).

  • 当前与终端交互的进程称为前台进程组.

  • 其余进程组称为后台进程组.

  • 根据POSIX.1定义: 挂断信号(SIGHUP)默认的动作是终止程序。


解释

  • 当终端接口检测到网络连接断开, 将挂断信号发送给控制进程(会话期首进程).

  • 如果会话期首进程终止,则该信号发送到该会话期前台进程组.

  • 一个进程退出导致一个孤儿进程组产生时, 如果任意一个孤儿进程组进程处于STOP状态, 发送 SIGHUP 和 SIGCONT 信号到该进程组中所有进程.

结论

  • 因此当网络断开或终端窗口关闭后, 也就是SSH断开以后, 控制进程收到 SIGHUP 信号退出, 会导致该会话期内其他进程退出.

  • 简而言之: 就是 ssh 打开以后, bash等都是他的子程序, 一旦ssh关闭, 系统将所有相关进程杀掉!! 导致一旦ssh关闭, 执行中的任务就取消了.


相关问题

为什么守护程序就算是 ssh 打开的, 关闭ssh也不会影响其运行?

  • 因为他们的程序特殊, 比如httpd –k start运行这个以后, 他不属于sshd这个进程组, 而是单独的进程组, 所以就算关闭了ssh, 和他也没有任何关系!

使用后台运行命令 & 能否将程序摆脱ssh进程组控制? 即关闭 ssh, 后台程序能否继续运行?

  • 只要是ssh 打开执行的一般命令,不是守护程序,无论加不加&,一旦关闭ssh,系统就会用SIGHUP终止.

如何解决方案

  • 在远端开启 tmux , 在 tmux 里运行程序, 此时运行的程序属于 tmux 的进程组, 不属于 ssh 进程组.

  • 使用 nohup 命令


Linux nohup 命令


nohup 英文全称 no hang up(不挂起),用于在系统后台不挂断地运行命令,退出终端不会影响程序的运行。

nohup 命令,在默认情况下(非重定向时),会输出一个名叫 nohup.out 的文件到当前目录下,如果当前目录的 nohup.out 文件不可写,输出重定向到 $HOME/nohup.out 文件中。

使用权限

所有使用者

语法格式

 nohup Command[Arg…][ &]

参数说明:

Command:要执行的命令。

Arg:一些参数,可以指定输出文件。

&:让命令在后台执行,终端退出后命令仍旧执行。

实例

以下命令在后台执行 root 目录下的 runoob.sh 脚本:

nohup /root/runoob.sh &

在终端如果看到以下输出说明运行成功:

appending output to nohup.out

这时我们打开 root 目录 可以看到生成了 nohup.out 文件。

如果要停止运行,你需要使用以下命令查找到 nohup 运行脚本到 PID,然后使用 kill 命令来删除:

ps -aux | grep "runoob.sh" 

参数说明:

  • a : 显示所有程序

  • u : 以用户为主的格式来显示

  • x : 显示所有程序,不区分终端机

另外也可以使用 ps -def | grep "runoob.sh" 命令来查找。

找到 PID 后,就可以使用 kill PID 来删除。

kill -9进程号PID

以下命令在后台执行 root 目录下的 runoob.sh 脚本,并重定向输入到 runoob.log 文件:

nohup /root/runoob.sh > runoob.log 2>&1&

2>&1 解释:

将标准错误 2 重定向到标准输出 &1 ,标准输出 &1 再被重定向输入到 runoob.log 文件中。

  • 0 – stdin (standard input,标准输入)

  • 1 – stdout (standard output,标准输出)

  • 2 – stderr (standard error,标准错误输出)