一、背景
    在linux命令行中执行程序,程序通常会占用当前终端,如果不启动新的终端就没法执行其他操作。简单可以通过'&'将程序放到后台执行,但是这种方法有个问题就是,一旦连接远程服务器的网络异常或者本机ssh客户端、系统等关闭亦或出现问题导致连接断开,那么放到后台执行的程序就会被终止。
    对于需要长时间运行的守护进程或者服务端程序这种异常断开造成的进程终止不可接受。下面就介绍三种解决这种问题的通用方案(不涉及程序改造)
 
二、nohup命令
    在启动程序命令后面添加&将程序放到后台作业队列中,管理任务队列中任务可以通过jobs等命令。
    但是任务队列中的任务通常情况下,其父进程都是当前终端的shell进程。而一旦父进程退出,则会发送hangup信号给所有子进程,子进程收到hangup以后也会退出。我们可以通过让后台进程忽略来自父进程的hangup信号或者修改后台进程的父进程id来避免后台进程退出。使用nohup命令执行的命令nohup ./tesh.sh & 可以忽略hangup信号(需要启动程序时将程序放到后台执行,否则关闭终端依然会导致进程结束),使用setsid命令  setsid ./test.sh & 可以将当前程序的父进程设置为init进程,这样就不会收到当前shell进程发出的hangup信号了。具体用法如下:
新启动程序
nohup ./test.sh >log 2>&1 &
setsid ./test.sh >log 2>&1 &
已运行程序
nohup -p PID
disown -h %n
  
  注:nohup命令会将所执行的命令的标准输出重定向到当前目录的nohup.out文件中(如果命令中没有重定向标准输出),但是不会重定向标准错误输出。其余的setsid、disown只是修改进程的sid,使其与当前shell脱离,但是并没有改变原命令的标准输出、标准错误输出,所以这些后台运行的进程,当需要标准输出或标准错误输出的时候,发现默认的输出位置终端不可用,就会报异常退出。因此,在运行后台进程时,尽量将利用 >log 2>&1 对命令的输出进行重定向(如表格中第一行)。
 
三、screen命令
    GNU Screen可以看作是窗口管理器的命令行界面版本。它提供了统一的管理多个会话的界面和相应的功能,大部分Linux发行版都默认带有screen。通过将screen会话与当前终端shell进程detach来避免当前终端shell的异常导致的screen中运行的程序的终止。
screen -S NAME
screen -S sxhlinux
新建一个名为sxhlinux的screen会话
screen -ls
screen -ls
查看当前系统中所有的screen会话
screen -d NAME
screen -d sxhlinux
将sxhlinux会话与当前shell终端分离
screen -r NAME
screen -r sxhlinux
在当前shell进程中与名为sxhlinux的进程重新连接
screen -R NAME
screen -R sxhlinux
同-r选项,另外如果sxhlinux不存在,
就会重新新建一个名为sxhlinux的screen会话
screen -x NAME 
screen -x sxhlinux
多个终端同时操作名为sxhlinux的screen会话,操作同步可见
 
在每个screen 会话中都有如下快捷键可以使用
ctrl-a c
在当前会话中创建一个新的的shell窗口
ctrl-a n/p
切换到下/上一个窗口
ctrl-a d
使当前会话与原shell detach
ctrl-a w
列出当前会话中的所有窗口
ctrl-a k
关闭当前窗口
ctrl-a x/q
锁定、解锁当前窗口
ctrl-a [/]
[启动复制模式(vi操作习惯),第一次空格键表示开始复制,第二次空格表示结束复制;
]将[复制的内容粘贴到当前位置
ctrl-a S/|
将当前屏幕水平/垂直分成两部分,可以通过ctrl-a TAB来切换
可以修改/etc/screenrc或者~/.screenrc配置文件来配置screen,选项vbell off/on 控制错误闪屏提醒。本文关注点在保证用户程序不因终端、网络异常等问题造成程序运行中断,因此这里有关screen只进行简单的介绍,有兴趣的可以搜索相关文章或者看官方document。
 
四、tmux命令
    虽然screen很好用,但是已经很多年没有添加新特性了,还存在一些bug。作为screen的替代者,tmux在各方面完全可以替代甚至超过screen,唯一的缺点是Linux发行版没有默认安装tmux,需要用户联网安装。下面就简单介绍tmux的使用方法:
tmux new -s NAME 
tmux new -s sxhlinux
创建一个
tmux detach -s NAME
tmux detach -s sxhlinux
将sxhlinux会话分离
tmux attach -t NAME
tmux a -t sxhlinux
重新连接sxhlinux会话
tmux ls
tmux ls
列出当前所有的tmux会话
tmux lsc [-t NAME]
tmux lsc [-t sxhlinux]
列出所有[连接到sxhlinux]的客户端
tmux rename -t OLD NEW
tmux rename -t sxh sxhlinux
将会话sxh重命名为sxhlinux
tmux kill-session -t NAME
tmux kill-session -t sxhlinux
关闭sxhlinux会话
 
tmux默认的快捷键组合前缀为ctrl b,不过为了和screen习惯保持一致,我们可以修改tmux的配置文件~/.tmux.conf来讲组合前缀改成ctrl a
ctrl-a c
同screen
ctrl-a d
同screen
ctrl-a f
在当前会话所有打开的窗口中搜索文本
ctrl-a n/p
同screen
ctrl-a &
关闭当前窗口
ctrl-a x
关闭当前会话
    修改的tmux配置文件如下(注:#以及后面的内容仅做说明,实际使用的时候请删除)
set -g prefix C-a   #配置快捷键前缀为ctrl a
unbind C-b #取消快捷键前缀ctrl b
unbind '%' #取消左右分pane的快捷键 %
bind | splitw -h #指定左右分pane的快捷键 |
bind k selectp -U #指定选择上方pane的快捷键 k
bind j selectp -D #指定选择上方pane的快捷键 j
bind h selectp -L #指定选择上方pane的快捷键 h
bind l selectp -R #指定选择上方pane的快捷键 l
 
通常情况下,如果系统重启原来的tmux会话就会丢失(因为tmux由一个server进程来保存相关会话信息,系统重启原来的server进程消失,所以之前的tmux会话也就不存在了)安装tmux-continuum插件解决tmux会话不能保存的问题。
  1. tmux-continuum插件要求tmux版本为1.9以上,目前CentOS 7 上的版本为1.8。 所以,需要我们去github的tmux项目中下载新版本的tmux替换系统中已有的老版本。
  2. 下载并安装tmux插件 git clone https://github.com/tmux-plugins/tpm ~/.tmux/plugins/tpm
  3. 编辑 ~/.tmux.conf文件,并在最后追加如下内容
    # Edit ~/.tmux.conf and added lines below at the bottom
    set -g @plugin 'tmux-plugins/tpm'
    set -g @plugin 'tmux-plugins/tmux-sensible'
    set -g @plugin 'tmux-plugins/tmux-resurrect'
    set -g @plugin 'tmux-plugins/tmux-continuum'
    set -g @continuum-restore 'on' # Initialize TMUX plugin manager (keep this line at the very bottom of tmux.conf)
    run '~/.tmux/plugins/tpm/tpm'
  4. 执行 tmux new -s test 创建一个临时的session,然后在session中执行 ctrl-a I 组合键安装tmux-continuum。安装完成后ctrl-d结束当前session。至此continuum插件安装完成。

  参考资料:https://github.com/tmux/tmux           https://github.com/tmux-plugins/tpm         https://github.com/tmux-plugins/tmux-continuum

 
五、总结
    nohup一般作为启动服务或者守护进程来执行一个单独的命令的情形下使用(记得输出重定向);screen和tmux可以作为日常连接远程开发服务器做开发使用,可以方便的切换各种工作台,而不用打开多个终端。

Linux 环境下程序不间断运行的更多相关文章

  1. linux环境下jmeter安装和运行

    linux环境部署: 在Linux服务器先安装jdk:2.以jdk-8u172-linux-x64.tar.gz为例:下载地址:http://www.oracle.com/technetwork/ja ...

  2. linux 环境下 eas console的运行

    1)访问 http://<HOST>:19000/easconsole/ 2)然后下载 jnlp 文件. 3)找个jre, 用javaws 运行 jnlp文件

  3. 编写第一个Linux环境下程序的编译,下载记录

    跟着韦东山学习Linux: 今天系统系统性的学了代码的编译下载,条记录一下: 一,代码:001_led_on.S,就把下面代码编译后Bin文件下载进2440处理器. /* * 点亮LED1: gpf4 ...

  4. Linux环境下安装JDK8

    Linux环境下搭建Java项目运行环境,首先要安装JDK,安装JDK8的步骤如下: 1 下载JDK安装包 下载地址:http://www.oracle.com/technetwork/java/ja ...

  5. Linux环境下部署完JDK后运行一个简单的Java程序

    前言 前一篇文章详细讲解了如何在Windows环境下安装虚拟机+Linux系统,并且成功部署了JDK. 不过部署完JDK之后,我们判断部署是否成功的依据是看"java -version&qu ...

  6. 针对 Linux 环境下 gdb 动态调试获取的局部变量地址与直接运行程序时不一致问题的解决方案

    基础的缓冲区溢出实践通常需要确定运行状态下程序中的某些局部变量的地址,如需要确定输入缓冲区的起始地址从而获得注入缓冲区中的机器指令的起始地址等.在 Linux 环境下,可通过 gdb 对程序进行动态调 ...

  7. SAAS云平台搭建札记: (二) Linux Ubutu下.Net Core整套运行环境的搭建

    最近做的项目,由于预算有限,公司决定不采购Windows服务器,而采购基于Linux的服务器. 一般的VPS服务器,如果使用Windows系统,那么Windows Server2012\2016安装好 ...

  8. 【ARM-Linux开发】Linux环境下使用eclipse开发C++动态链接库程序

    Linux环境下使用eclipse开发C++动态链接库程序 Linux中也有类似windows中DLL的变成方法,只不过名称不同而已.在Linux中,动态链接叫做Standard Object,生成的 ...

  9. linux 环境下运行STS时 出现must be available in order to run STS

    linux 环境下运行ECLIPSE时 出现 “ A Java Runtime Environment (JRE) or Java Development Kit (JDK) must be avai ...

随机推荐

  1. 让我们一起爱(装)上Homestead吧

    本文是Laravel实战:任务管理系统(一)的扩展阅读原文链接 先来点残酷现实:  真正用过homestead的,一般不会问homestead到底好在哪里 如果你还没有爱上homestead,只能说明 ...

  2. centos7 安装jdk 1.8

    1.下载jdk1.8  for linux的安装包 jdk-8u11-linux-x64.tar.gz,下载地址:http://download.oracle.com/otn-pub/java/jdk ...

  3. 1.JavaScript 教程:基础语法

    简介: JavaScript web 开发人员必须学习的 3 门语言中的一门: HTML 定义了网页的内容 CSS 描述了网页的布局 JavaScript 网页的行为 用法: (1)HTML 中的脚本 ...

  4. 前后端分离之CORS和WebApi

    目前的项目是前端mv*+api的方式进行开发的,以前都是没有跨域的方案,前后端人员在同一个解决方案里边进行开发,前端人员要用IIS或VS来开发和调试Api,这样就很不方便,迫切需要跨域访问Api. 评 ...

  5. jdk源码->集合->HashSet

    类的属性 public class HashSet<E> extends AbstractSet<E> implements Set<E>, Cloneable, ...

  6. ueditor表格边框没有颜色的解决

    问题: 用ueditor画表格,会发现表格存在,但是表格边框没有颜色. 解决方法: 需要对js文件中的样式进行修改,这里我引用的编辑器样式文件是ueditor.all.min.js,所以先找到该文件, ...

  7. PHP 构造方法 __construct()(转)

    PHP 析构方法 __destruct() 构造方法是类中的一个特殊方法.当使用 new 操作符创建一个类的实例时,构造方法将会自动调用,其名称必须是 __construct() . 在一个类中只能声 ...

  8. php与HTML交互问题

    1.将表单中的action属性值设为PHP路径,则网页会跳转到这个网址 <html> <body> <form action="welcome.php" ...

  9. 【Java】泛型学习笔记

    参考书籍 <Java核心技术:卷1> 泛型, 先睹为快 先通过一个简单的例子说明下Java中泛型的用法: 泛型的基本形式类似于模板, 通过一个类型参数T, 你可以"私人定制&qu ...

  10. ABP 多租户 对应多数据库 租户启动报错

    什么是多租户? “软件多租户是指一个软件体系结构,其中一个软件实例在一个服务器上运行,并为多个租户提供服务*租户是一组共享具有软件实例特定权限的公共访问权限的用户. 架构中,软件应用程序旨在为每个租户 ...