分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow
也欢迎大家转载本篇文章。分享知识,造福人民,实现我们中华民族伟大复兴!
| CSDN | GitHub |
|---|---|
| 解决Linux关闭终端(关闭SSH等)后运行的程序自动停止 | AderXCoding/system/tools/ssh_exit |
本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可
1 问题发现
之前在服务器上起一个python的服务, 放到后台运行. 我关闭这个SSH之后,该服务不可用,再次登入到服务器,已经没有这个python进程.
为此我写了一个测试程序来描述此问题
/////////////////////// hello.c/////////////////////#include <stdio.h>#include <stdlib.h>#include <unistd.h>int main(void){ while(1) { printf("pid = %d, I am coming...\n", getpid( )); sleep(3); } return EXIT_SUCCESS;}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
我们在一个ssh中编译后启动该进程
gcc hello.c -o hello -std=gnu99 -Wall./hello
- 1
- 2
然后再开一个ssh, 我们用pidof hello来查看进程的pid信息, 显示出进程的pid为29738
接着我们关掉那个启动了hello的ssh, 重新用pidof hello再次查看进程信息, 发现进程已经没了
其他进程的影响
守护进程不受此影响, 因为守护进程比较特殊, 不属于sshd这个进程组 而是单独的进程组,所以就算关闭了ssh,和他也没有任何关系, 如果不这样的话, 你发现nfs服务没开. 你用ssh登录, 开启了守护进程, 如果ssh退出后守护进程也退出了, 那岂不是白忙活了
使用后台运行命令&, 不能将程序摆脱ssh进程组控制呢, 因为其本质仍然属于此进程会话组的进程
2 问题定位
通过上面问题的表象,可以发现是跟SSH关闭有关。为什么ssh关闭,会导致正在运行的程序死掉。通过查看相关的资料,发现真正的元凶是SIGHUP信号导致的.
在linux中,有下面几个概念:
| 概念 | 描述 |
|---|---|
| 进程组 | 一个或多个进程的集合,每一个进程组都有唯一一个进程组ID,即进程组 |
| 会话器 | 一个或多个进程组的集合,有唯一一个会话期首进程(session leader). 会话期ID为首进程的ID |
| 控制进程 | 与控制终端连接的会话期首进程叫做控制进程 |
当前与终端交互的进程称为前台进程组. 其余进程组称为后台进程组.
一般缩写:
PID = 进程ID (由内核根据延迟重用算法生成)PPID = 父进程ID(只能由内核修改)PGID = 进程组ID(子进程、父进程都能修改)SID = 会话ID(进程自身可以修改,但有限制,详见下文)TPGID= 控制终端进程组ID(由控制终端修改,用于指示当前前台进程组)
- 1
- 2
- 3
- 4
- 5
会话和进程组的关系:
每次用户登录终端时会产生一个会话(session). 从用户登录开始到用户退出为止,这段时间内在该终端执行的进程都属于这一个会话
每个进程除了有一进程ID之外,还属于一个进程组(Process Group)。进程组是一个或多个进程的集合,每个进程组有一个唯一的进程组ID。多个进程属于进程组的情况是多个进程用管道“|”号连接进行执行。如果在命令行执行单个进程时这个进程组只有这一个进程.
挂断信号(SIGHUP)默认的动作是终止程序.
当终端接口检测到网络连接断开,将挂断信号发送给控制进程(会话期首进程)
如果会话期首进程终止,则该信号发送到该会话期前台进程组.
一个进程退出导致一个孤儿进程组中产生时,如果任意一个孤儿进程组进程处于STOP状态,发送SIGHUP和SIGCONT信号到该进程组中所有进程.
结论:因此当网络断开或终端窗口关闭后,也就是SSH断开以后,控制进程收到SIGHUP信号退出,会导致该会话期内其他进程退出.
简而言之:就是ssh 打开以后,bash等都是他的子程序,一旦ssh关闭,系统将所有相关进程杀掉!! 导致一旦ssh关闭,执行中的任务就取消了.
3 解决的办法
3.1 nohup命令
如果你正在运行一个进程,而且你觉得在退出帐户时该进程还不会结束,那么可以使用nohup命令. 该命令可以在你退出帐户/关闭终端之后继续运行相应的进程. nohup就是不挂起的意思.
我们现在开始启动服务 python pyserver.py,并且希望在后台运行.我们就可以使用nohup,命令如下:
nohup ./hello &
- 1
此时默认地程序运行的输出信息放到当前文件夹的nohup.out 文件中去,加不加&并不会影响这个命令。只是让程序前台或者后台运行而已
然后另外一个ssh中, 我们用pidof hello来查看进程的pid信息, 显示出进程的pid为29738
接着我们关掉那个启动了hello的ssh, 重新用pidof hello再次查看进程信息, 发现进程仍然存在
| nohup命令 | 说明 |
|---|---|
| 用途 | 挂断地运行命令 |
| 语法 | nohup Command [ Arg … ] [ & ] |
| 描述 | nohup 命令运行由 Command 参数和任何相关的 Arg 参数指定的命令,忽略所有挂断(SIGHUP)信号。在注销后使用 nohup 命令运行后台中的程序。要运行后台中的 nohup 命令,添加 & ( 表示“and”的符号)到命令的尾部 |
无论是否将 nohup 命令的输出重定向到终端,输出都将附加到当前目录的 nohup.out 文件中。如果当前目录的 nohup.out 文件不可写,输出重定向到 $HOME/nohup.out 文件中。如果没有文件能创建或打开以用于追加,那么 Command 参数指定的命令不可调用。如果标准错误是一个终端,那么把指定的命令写给标准错误的所有输出作为标准输出重定向到相同的文件描述符.
退出状态, 该命令返回下列出口值
| 退出值 | 描述 |
|---|---|
| 126 | 可以查找但不能调用 Command 参数指定的命令 |
| 127 | nohup 命令发生错误或不能查找由 Command 参数指定的命令, 否则,nohup 命令的退出状态是 Command 参数指定命令的退出状态 |
3.2 screen命令
如果想在关闭ssh连接后刚才启动的程序继续运行怎么办, 可以使用nohup.
但是如果要求第二天来的时候. 一开ssh, 还能查看到昨天运行的程序的状态,
然后继续工作,这时nohup是不行了, 需要使用screen来达到这个目的.
虽然nohup很容易使用,但还是比较“简陋”的,对于简单的命令能够应付过来,对于复杂的需要人机交互的任务就麻烦了
其实我们可以使用一个更为强大的实用程序screen。流行的Linux发行版通常会自带screen实用程序,如果没有的话,可以从GNU screen的官方网站下载
执行screen , 按任意键进入子界面;
我用./hello命令开始执行,如果下班了,但是想关闭ssh以后./hello继续运行,那么按ctrl+a再按d
这样暂停了子界面,会显示[detached]的字样,这时候 我回到了父界面;
用screen –ls查看目前子界面的状态screen -ls
There is a screen on: 10869.pts-14.kylin (Detached)1 Socket in /var/run/screens/S-gatieme.
- 1
- 2
- 3
如果回到子界面 用screen –r 22292,一下子弹到了./hello的子界面;
给我老师的人工智能教程打call!http://blog.csdn.net/jiangjunshow
新的改变
我们对Markdown编辑器进行了一些功能拓展与语法支持,除了标准的Markdown编辑器功能,我们增加了如下几点新功能,帮助你用它写博客:
- 全新的界面设计 ,将会带来全新的写作体验;
- 在创作中心设置你喜爱的代码高亮样式,Markdown 将代码片显示选择的高亮样式 进行展示;
- 增加了 图片拖拽 功能,你可以将本地的图片直接拖拽到编辑区域直接展示;
- 全新的 KaTeX数学公式 语法;
- 增加了支持甘特图的mermaid语法1 功能;
- 增加了 多屏幕编辑 Markdown文章功能;
- 增加了 焦点写作模式、预览模式、简洁写作模式、左右区域同步滚轮设置 等功能,功能按钮位于编辑区域与预览区域中间;
- 增加了 检查列表 功能。
功能快捷键
撤销:Ctrl/Command + Z
重做:Ctrl/Command + Y
加粗:Ctrl/Command + B
斜体:Ctrl/Command + I
标题:Ctrl/Command + Shift + H
无序列表:Ctrl/Command + Shift + U
有序列表:Ctrl/Command + Shift + O
检查列表:Ctrl/Command + Shift + C
插入代码:Ctrl/Command + Shift + K
插入链接:Ctrl/Command + Shift + L
插入图片:Ctrl/Command + Shift + G
合理的创建标题,有助于目录的生成
直接输入1次#,并按下space后,将生成1级标题。
输入2次#,并按下space后,将生成2级标题。
以此类推,我们支持6级标题。有助于使用TOC语法后生成一个完美的目录。
如何改变文本的样式
强调文本 强调文本
加粗文本 加粗文本
标记文本
删除文本
引用文本
H2O is是液体。
210 运算结果是 1024.
插入链接与图片
链接: link.
图片:
带尺寸的图片:
当然,我们为了让用户更加便捷,我们增加了图片拖拽功能。
如何插入一段漂亮的代码片
去博客设置页面,选择一款你喜欢的代码片高亮样式,下面展示同样高亮的 代码片.
// An highlighted block var foo = 'bar';
生成一个适合你的列表
- 项目
- 项目
- 项目
- 项目
- 项目1
- 项目2
- 项目3
- 计划任务
- 完成任务
创建一个表格
一个简单的表格是这么创建的:
| 项目 | Value |
|---|---|
| 电脑 | $1600 |
| 手机 | $12 |
| 导管 | $1 |
设定内容居中、居左、居右
使用:---------:居中
使用:----------居左
使用----------:居右
| 第一列 | 第二列 | 第三列 |
|---|---|---|
| 第一列文本居中 | 第二列文本居右 | 第三列文本居左 |
SmartyPants
SmartyPants将ASCII标点字符转换为“智能”印刷标点HTML实体。例如:
| TYPE | ASCII | HTML |
|---|---|---|
| Single backticks | 'Isn't this fun?' |
‘Isn’t this fun?’ |
| Quotes | "Isn't this fun?" |
“Isn’t this fun?” |
| Dashes | -- is en-dash, --- is em-dash |
– is en-dash, — is em-dash |
创建一个自定义列表
- Markdown
- Text-to-HTML conversion tool
- Authors
- John
- Luke
如何创建一个注脚
一个具有注脚的文本。2
注释也是必不可少的
Markdown将文本转换为 HTML。
KaTeX数学公式
您可以使用渲染LaTeX数学表达式 KaTeX:
Gamma公式展示 是通过欧拉积分
你可以找到更多关于的信息 LaTeX 数学表达式here.
新的甘特图功能,丰富你的文章
gantt
dateFormat YYYY-MM-DD
title Adding GANTT diagram functionality to mermaid
section 现有任务
已完成 :done, des1, 2014-01-06,2014-01-08
进行中 :active, des2, 2014-01-09, 3d
计划一 : des3, after des2, 5d
计划二 : des4, after des3, 5d
- 关于 甘特图 语法,参考 这儿,
UML 图表
可以使用UML图表进行渲染。 Mermaid. 例如下面产生的一个序列图::
这将产生一个流程图。:
- 关于 Mermaid 语法,参考 这儿,
FLowchart流程图
我们依旧会支持flowchart的流程图:
- 关于 Flowchart流程图 语法,参考 这儿.
导出与导入
导出
如果你想尝试使用此编辑器, 你可以在此篇文章任意编辑。当你完成了一篇文章的写作, 在上方工具栏找到 文章导出 ,生成一个.md文件或者.html文件进行本地保存。
导入
如果你想加载一篇你写过的.md文件或者.html文件,在上方工具栏可以选择导入功能进行对应扩展名的文件导入,
继续你的创作。
-
注脚的解释 ↩︎
| CSDN | GitHub |
|---|---|
| 解决Linux关闭终端(关闭SSH等)后运行的程序自动停止 | AderXCoding/system/tools/ssh_exit |
本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可
1 问题发现
之前在服务器上起一个python的服务, 放到后台运行. 我关闭这个SSH之后,该服务不可用,再次登入到服务器,已经没有这个python进程.
为此我写了一个测试程序来描述此问题
/////////////////////// hello.c/////////////////////#include <stdio.h>#include <stdlib.h>#include <unistd.h>int main(void){ while(1) { printf("pid = %d, I am coming...\n", getpid( )); sleep(3); } return EXIT_SUCCESS;}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
我们在一个ssh中编译后启动该进程
gcc hello.c -o hello -std=gnu99 -Wall./hello
- 1
- 2
然后再开一个ssh, 我们用pidof hello来查看进程的pid信息, 显示出进程的pid为29738
接着我们关掉那个启动了hello的ssh, 重新用pidof hello再次查看进程信息, 发现进程已经没了
其他进程的影响
守护进程不受此影响, 因为守护进程比较特殊, 不属于sshd这个进程组 而是单独的进程组,所以就算关闭了ssh,和他也没有任何关系, 如果不这样的话, 你发现nfs服务没开. 你用ssh登录, 开启了守护进程, 如果ssh退出后守护进程也退出了, 那岂不是白忙活了
使用后台运行命令&, 不能将程序摆脱ssh进程组控制呢, 因为其本质仍然属于此进程会话组的进程
2 问题定位
通过上面问题的表象,可以发现是跟SSH关闭有关。为什么ssh关闭,会导致正在运行的程序死掉。通过查看相关的资料,发现真正的元凶是SIGHUP信号导致的.
在linux中,有下面几个概念:
| 概念 | 描述 |
|---|---|
| 进程组 | 一个或多个进程的集合,每一个进程组都有唯一一个进程组ID,即进程组 |
| 会话器 | 一个或多个进程组的集合,有唯一一个会话期首进程(session leader). 会话期ID为首进程的ID |
| 控制进程 | 与控制终端连接的会话期首进程叫做控制进程 |
当前与终端交互的进程称为前台进程组. 其余进程组称为后台进程组.
一般缩写:
PID = 进程ID (由内核根据延迟重用算法生成)PPID = 父进程ID(只能由内核修改)PGID = 进程组ID(子进程、父进程都能修改)SID = 会话ID(进程自身可以修改,但有限制,详见下文)TPGID= 控制终端进程组ID(由控制终端修改,用于指示当前前台进程组)
- 1
- 2
- 3
- 4
- 5
会话和进程组的关系:
每次用户登录终端时会产生一个会话(session). 从用户登录开始到用户退出为止,这段时间内在该终端执行的进程都属于这一个会话
每个进程除了有一进程ID之外,还属于一个进程组(Process Group)。进程组是一个或多个进程的集合,每个进程组有一个唯一的进程组ID。多个进程属于进程组的情况是多个进程用管道“|”号连接进行执行。如果在命令行执行单个进程时这个进程组只有这一个进程.
挂断信号(SIGHUP)默认的动作是终止程序.
当终端接口检测到网络连接断开,将挂断信号发送给控制进程(会话期首进程)
如果会话期首进程终止,则该信号发送到该会话期前台进程组.
一个进程退出导致一个孤儿进程组中产生时,如果任意一个孤儿进程组进程处于STOP状态,发送SIGHUP和SIGCONT信号到该进程组中所有进程.
结论:因此当网络断开或终端窗口关闭后,也就是SSH断开以后,控制进程收到SIGHUP信号退出,会导致该会话期内其他进程退出.
简而言之:就是ssh 打开以后,bash等都是他的子程序,一旦ssh关闭,系统将所有相关进程杀掉!! 导致一旦ssh关闭,执行中的任务就取消了.
3 解决的办法
3.1 nohup命令
如果你正在运行一个进程,而且你觉得在退出帐户时该进程还不会结束,那么可以使用nohup命令. 该命令可以在你退出帐户/关闭终端之后继续运行相应的进程. nohup就是不挂起的意思.
我们现在开始启动服务 python pyserver.py,并且希望在后台运行.我们就可以使用nohup,命令如下:
nohup ./hello &
- 1
此时默认地程序运行的输出信息放到当前文件夹的nohup.out 文件中去,加不加&并不会影响这个命令。只是让程序前台或者后台运行而已
然后另外一个ssh中, 我们用pidof hello来查看进程的pid信息, 显示出进程的pid为29738
接着我们关掉那个启动了hello的ssh, 重新用pidof hello再次查看进程信息, 发现进程仍然存在
| nohup命令 | 说明 |
|---|---|
| 用途 | 挂断地运行命令 |
| 语法 | nohup Command [ Arg … ] [ & ] |
| 描述 | nohup 命令运行由 Command 参数和任何相关的 Arg 参数指定的命令,忽略所有挂断(SIGHUP)信号。在注销后使用 nohup 命令运行后台中的程序。要运行后台中的 nohup 命令,添加 & ( 表示“and”的符号)到命令的尾部 |
无论是否将 nohup 命令的输出重定向到终端,输出都将附加到当前目录的 nohup.out 文件中。如果当前目录的 nohup.out 文件不可写,输出重定向到 $HOME/nohup.out 文件中。如果没有文件能创建或打开以用于追加,那么 Command 参数指定的命令不可调用。如果标准错误是一个终端,那么把指定的命令写给标准错误的所有输出作为标准输出重定向到相同的文件描述符.
退出状态, 该命令返回下列出口值
| 退出值 | 描述 |
|---|---|
| 126 | 可以查找但不能调用 Command 参数指定的命令 |
| 127 | nohup 命令发生错误或不能查找由 Command 参数指定的命令, 否则,nohup 命令的退出状态是 Command 参数指定命令的退出状态 |
3.2 screen命令
如果想在关闭ssh连接后刚才启动的程序继续运行怎么办, 可以使用nohup.
但是如果要求第二天来的时候. 一开ssh, 还能查看到昨天运行的程序的状态,
然后继续工作,这时nohup是不行了, 需要使用screen来达到这个目的.
虽然nohup很容易使用,但还是比较“简陋”的,对于简单的命令能够应付过来,对于复杂的需要人机交互的任务就麻烦了
其实我们可以使用一个更为强大的实用程序screen。流行的Linux发行版通常会自带screen实用程序,如果没有的话,可以从GNU screen的官方网站下载
执行screen , 按任意键进入子界面;
我用./hello命令开始执行,如果下班了,但是想关闭ssh以后./hello继续运行,那么按ctrl+a再按d
这样暂停了子界面,会显示[detached]的字样,这时候 我回到了父界面;
用screen –ls查看目前子界面的状态screen -ls
There is a screen on: 10869.pts-14.kylin (Detached)1 Socket in /var/run/screens/S-gatieme.
- 1
- 2
- 3
如果回到子界面 用screen –r 22292,一下子弹到了./hello的子界面;