一、背景
    在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. 为什么我不愿意用ECharts

    前言 ECharts是百度一个使用 JavaScript 实现的开源可视化库,提供了创建多种多样的图标方式,包括坐标系,图例,提示,工具箱等基础组件,并在此上构建出折线图.柱状图.散点图.K线图.饼图 ...

  2. CentOS6.x机器安装Azure CLI2.0【1】

    安装Azure CLI 2.0的前提是:机器中必须有 Python 2.7.x 或 Python 3.x.如果机器中没有其中任何一个Python版本,请及时安装 1.准备一台CentOS 6.9的机器 ...

  3. junit4X系列源码--总体介绍

    原文出处:http://www.cnblogs.com/caoyuanzhanlang/p/3530267.html.感谢作者的无私分享. Junit是一个可编写重复测试的简单框架,是基于Xunit架 ...

  4. Linkin大话eclipse快捷键

    刚来这家公司的时候,作为菜鸟的我在帮别人调试代码的时候,有人说我快捷键使用的很熟悉. 呵呵,工欲善其事必先利其器,以下这些快捷键是最常用的也是要必须记住的. [Ctrl开头] Ctrl+1:快速修复 ...

  5. mysql主从配置主主配置

    一.     概述  MySQL从3.23.15版本以后提供数据库复制(replication)功能,利用该功能可以实现两个数据库同步.主从模式.互相备份模式的功能.本文档主要阐述了如何在linux系 ...

  6. Win2003 设置远程连接限制数

    在开发过程中,很多同事需要连接到一台Win2003服务器,但是连接人数超过了10个,就连接不上了.想设置一下连接限制数,可以如下操作: 1:在运行里面输入gpedit.msc后,弹出"本地计 ...

  7. SQL Server——存储过程

    我想从下面几个方面大概的讲述下存储过程,可能有些知识点是你没有注意的,也可能有些知识点我不知道,欢迎大家指点指点.如有不足,欢迎指教! 存储过程概念 存储过程优点 存储过程的接口 存储过程的解析.编译 ...

  8. grails项目中(DB的相关操作)

    grails项目中(DB的相关操作) save:保存Domain对象的数据到对应的库表中(可能是insert也可能是update) findBy: 动态方法,查找并返回第一条记录,方法名可以变化 eg ...

  9. php 通过curl获取远程数据,返回的是一个数组型的字符串,高手帮忙如何将这个数组类型的字符串变成数组。

    如 Array([0] => Array([0] => Array([kd_status] => 已签收[kd_time] => 2014-04-30 18:59:43 [b] ...

  10. 基于tomcat+springMVC搭建基本的前后台交互系统

    一.摘要 1.所需软件列表: 1) tomcat :  apache-tomcat-7.0.54  服务端容器 2) Intellij: Intellij IDEA 14.0.3         开发 ...