阅读更多

0顶
0踩

操作系统

转载新闻 Linux环境下如何让进程在后台运行

2017-03-16 16:09 by 副主编 jihong10102006 评论(0) 有6849人浏览

一. nohup / setsid / &
使用场景:如果只是临时有一个命令需要长时间运行,什么方法能最简便的保证它在后台稳定运行呢?

我们的解决办法就有两种途径:要么让进程忽略 HUP 信号,要么让进程运行在新的会话里从而成为不属于此终端的子进程。

解决方法:
1.nohup
只需在要处理的命令前加上 nohup 即可,标准输出和标准错误缺省会被重定向到 nohup.out 文件中。一般我们可在结尾加上"&"来将命令同时放入后台运行,也可用>filename 2>&1来更改缺省的重定向文件名。
    [root@pvcent107 ~]# nohup ping www.ibm.com & 
    [1] 3059 
    nohup: appending output to `nohup.out' 
    [root@pvcent107 ~]# ps -ef |grep 3059 
    root      3059   984  0 21:06 pts/3    00:00:00 ping www.ibm.com 
    root      3067   984  0 21:06 pts/3    00:00:00 grep 3059 
    [root@pvcent107 ~]# 

2. setsid
setsid 的使用也是非常方便的,也只需在要处理的命令前加上 setsid 即可。
    [root@pvcent107 ~]# setsid ping www.ibm.com 
    [root@pvcent107 ~]# ps -ef |grep www.ibm.com 
    root     31094     1  0 07:28 ?        00:00:00 ping www.ibm.com 
    root     31102 29217  0 07:29 pts/4    00:00:00 grep www.ibm.com 
    [root@pvcent107 ~]# 

上例中我们的进程 ID(PID)为31094,而它的父 ID(PPID)为1(即为 init 进程 ID),并不是当前终端的进程 ID。请将此例与nohup 例中的父 ID 做比较。

3. &
将一个或多个命名包含在“()”中就能让这些命令在子 shell 中运行中 当我们将"&"也放入“()”内之后,我们就会发现所提交的作业并不在作业列表中,也就是说,是无法通过jobs来查看的。
    [root@pvcent107 ~]# (ping www.ibm.com &) 
    [root@pvcent107 ~]# ps -ef |grep www.ibm.com 
    root     16270     1  0 14:13 pts/4    00:00:00 ping www.ibm.com 
    root     16278 15362  0 14:13 pts/4    00:00:00 grep www.ibm.com 
    [root@pvcent107 ~]# 

新提交的进程的父 ID(PPID)为1(init 进程的 PID),并不是当前终端的进程 ID。因此并不属于当前终端的子进程,从而也就不会受到当前终端的 HUP 信号的影响了。

二. disown
使用场景:如果事先在命令前加上 nohup 或者 setsid 就可以避免 HUP 信号的影响。但是如果我们未加任何处理就已经提交了命令,该如何补救才能让它避免 HUP 信号的影响呢?

解决方法:这时想加 nohup 或者 setsid 已经为时已晚,只能通过作业调度和 disown 来解决这个问题了
  • 用disown -h jobspec来使某个作业忽略HUP信号。
  • 用disown -ah 来使所有的作业都忽略HUP信号。
  • 用disown -rh 来使正在运行的作业忽略HUP信号。
当使用过 disown 之后,会将把目标作业从作业列表中移除,我们将不能再使用jobs来查看它,但是依然能够用ps -ef查找到它。

disown 示例1(如果提交命令时已经用“&”将命令放入后台运行,则可以直接使用“disown”)
    [root@pvcent107 build]# cp -r testLargeFile largeFile & 
    [1] 4825 
    [root@pvcent107 build]# jobs 
    [1]+  Running                 cp -i -r testLargeFile largeFile & 
    [root@pvcent107 build]# disown -h %1 
    [root@pvcent107 build]# ps -ef |grep largeFile 
    root      4825   968  1 09:46 pts/4    00:00:00 cp -i -r testLargeFile largeFile 
    root      4853   968  0 09:46 pts/4    00:00:00 grep largeFile 
    [root@pvcent107 build]# logout 

disown 示例2(如果提交命令时未使用“&”将命令放入后台运行,可使用 CTRL-z 和“bg”将其放入后台,再使用“disown”)
    [root@pvcent107 build]# cp -r testLargeFile largeFile2 
     
    [1]+  Stopped                 cp -i -r testLargeFile largeFile2 
    [root@pvcent107 build]# bg %1 
    [1]+ cp -i -r testLargeFile largeFile2 & 
    [root@pvcent107 build]# jobs 
    [1]+  Running                 cp -i -r testLargeFile largeFile2 & 
    [root@pvcent107 build]# disown -h %1 
    [root@pvcent107 build]# ps -ef |grep largeFile2 
    root      5790  5577  1 10:04 pts/3    00:00:00 cp -i -r testLargeFile largeFile2 
    root      5824  5577  0 10:05 pts/3    00:00:00 grep largeFile2 
    [root@pvcent107 build]# 

三: screen
使用场景: 我们已经知道了如何让进程免受 HUP 信号的影响,但是如果有大量这种命令需要在稳定的后台里运行,如何避免对每条命令都做这样的操作呢?

解决方案: 此时最方便的方法就是 screen 了。简单的说,screen 提供了 ANSI/VT100 的终端模拟器,使它能够在一个真实终端下运行多个全屏的伪终端。screen 的参数很多,具有很强大的功能,
  • 用screen -dmS (sessionName)来建立一个处于断开模式下的会话(并指定其会话名)。
  • 用screen -list 来列出所有会话。
  • 用screen -r (sessionName)来重新连接指定会话。
  • 用快捷键CTRL-a d 来暂时断开当前会话。
screen实例
    [root@pvcent107 ~]# screen -dmS Urumchi 
    [root@pvcent107 ~]# screen -list 
    There is a screen on: 
            12842.Urumchi   (Detached) 
    1 Socket in /tmp/screens/S-root. 
     
    [root@pvcent107 ~]# screen -r Urumchi 

当我们用“-r”连接到 screen 会话后,我们就可以在这个伪终端里面为所欲为,再也不用担心 HUP 信号会对我们的进程造成影响,也不用给每个命令前都加上“nohup”或者“setsid”了。

1.未使用 screen 时新进程的进程树
    [root@pvcent107 ~]# ping www.google.com & 
    [1] 9499 
    [root@pvcent107 ~]# pstree -H 9499 
    init─┬─Xvnc 
         ├─acpid 
         ├─atd 
         ├─2*[sendmail]     
         ├─sshd─┬─sshd───bash───pstree 
         │       └─sshd───bash───ping 

未使用 screen 时我们所处的 bash 是 sshd 的子进程,当 ssh 断开连接时,HUP 信号自然会影响到它下面的所有子进程(包括我们新建立的 ping 进程)。

2.使用了 screen 后新进程的进程树
    [root@pvcent107 ~]# screen -r Urumchi 
    [root@pvcent107 ~]# ping www.ibm.com & 
    [1] 9488 
    [root@pvcent107 ~]# pstree -H 9488 
    init─┬─Xvnc 
         ├─acpid 
         ├─atd 
         ├─screen───bash───ping 
         ├─2*[sendmail] 

而使用了 screen 后就不同了,此时 bash 是 screen 的子进程,而 screen 是 init(PID为1)的子进程。那么当 ssh 断开连接时,HUP 信号自然不会影响到 screen 下面的子进程了。
  • 大小: 155.3 KB
来自: segmentfault
0
0
评论 共 0 条 请登录后发表评论

发表评论

您还没有登录,请您登录后再发表评论

相关推荐

  • C# Windows API内存操作全解析:10步教你轻松玩转内存管理,你get了吗?

    通过今天的分享,相信你现在应该对C#中如何通过Windows API进行内存操作有了更深一步的理解。无论是读取外部进程的数据,还是优化自身程序的性能,这些技巧都将为你提供强有力的支持。那么问题来了,你会选择将哪些新特性应用到自己的项目当中呢?期待听到你的想法!这就是关于“C# Windows API内存操作全解析:10步教你轻松玩转内存管理,你get了吗?”的所有内容啦!是不是觉得既有趣又实用呢?如果你也想试试看的话,不妨按照上面的指南动手做一做吧!如果有任何疑问或是想要分享自己的见解,请随时留言交流哦。

  • JMP Call hook

    JMP与CALL HOOK之间的较量,攻防之战

  • 游戏修改器制作教程四:用API读写内存

    上一章讲了用CE读写内存,本章讲如何自己编程实现 本文以制作东方辉针城修改器的实战讲解读写内存

  • Windows核心编程_修改其它进程里的内存值+示例:修改游戏分数

    最近一直忙于Opencv图像处理方面的学习,以及工作,没有更新C/C++专栏方面的博客了,所以今天就给大家写个应用层方面的编程代码,可用于参考学习,本篇博客将运用WindowsSDK库所提供的API来编写一个修改其他进程里变量值的程序。在开始实际编写代码之前,先给大家介绍一下所需函数:OpenProcess、VirtualProtectEx、ReadProcessMemory、WriteProce...

  • 关于e语言修改内存

    API与内存

  • hook模板x86/x64通用版(1)--x64下的jmp远跳、远call指令

    我一直在寻找能用,通用,简短的x64远跳河远call指令 现在用的跟大家分享一下,哪位大牛有更好的希望可以指点一下。 还有pushad/popad在x64下有什么好的替代品么?求指点。 远跳: 代码: push 地址的低32位 mov dword ptr ss:[rsp+4],地址的高32位 ret 远call: 代码: call @next   //e8 00

  • Windows内存管理的API函数

    数据所在的内存地址,内存最小存储单元是字节,在32位系统上使用32位数来表示内存地址. 一共可以表示2^32次 地址空间: 32位可以使用4GB内存,那么地址空间就是0x00000000~0xFFFFFFFF 物理内存: 硬件系统中真实存在的存储空间称为物理内存. 虚

  • 【汇编】JMP跳转指令的指令长度、直接转移与间接转移、段内跳转与段间跳转

    指令长度=操作码的长度+操作数地址的长度 1.段内跳转 JMP指令占1个字节。 操作数的地址长度 = (目标地址-指令当前地址)//若能用1个字节表示,则占用1个字节,那么整体指令长度为2个字节;若需2个字节表示,则占用2个字节,此时整体指令为3个字节。 比如: 0113 jmp 0185 ;0185h-0113h=72h,72h可用1个字节表示,加上JMP的一个字节,一共指令长度为

  • 【干货】【C语言实现HOOK 跳转和用C语言变量存储目标进程的寄存器数值】 CALL / JMP/ MOV 变量内存地址

    有的时候要写CALL ,就用下面的 void WriteCall(DWORD ProcAddr,LPVOID lpData) { BYTE _data[5]; _data[0]=0xE8; DWORD OldPro; VirtualProtect((LPVOID)(ProcAddr),5,PAGE_EXECUTE_READWRITE,&OldPro); memcpy((LPVOID)(_data+1),lpData,4);//_data是变量的内存地址 memcpy((LPVOID)(ProcAdd

  • JMP、Hook

    #include "stdio.h"   #include "tchar.h"   #include "windows.h"         //offset=目标地址-(jmp指令起始地址+5)   //跳转指令解码:[0xe9][offset]   //  offset:有符号整型,四字节.它等于jmp指令的下一指令地址到目标地址的相对距离   //  计算公式:   // 

  • c#中用windows api函数修改内存数据

    这个问题来自伴水的《划拳机器人》,对本文用途感兴趣的朋友请大致阅读伴水的帖子,在帖子中我用这个方法写了剪刀五号,战绩不错,当然属于作弊的方法了。剪刀五号的思路就是每次出拳,尽量让对方能赢,然后根据一个地址段来扫描内存中对方所赢的局数的保存地址,找到后在得到比赛结果时把内存数据改掉。这个类似以前打单机游戏时用的fpe之类的修改工具。当然,如果对方故意犯规,一局也不赢,你是找不到他的地址的

  • 64位汇编跳转,64位HOOK

    传统JMP 只支持32位的程序, 64位程序的地址有 8个字节 ,直接JMP只支持4个字节,跳转的地址和HOOK地址相减超过4个字节 就会出错了 在64位 可以这样跳, push rax 保存寄存器 mov rax,目标绝对地址 jmp rax pop rax 还原寄存器 很简单,如果你分配的内存地址是64位的话。如: 504BEA0000, 根据我帖子里的回复,你可以这样 方...

  • java memoryfile_如何在Java中使用文件操作API: java.nio.file.Path?- marcobehler

    本文有关学习如何在Java中使用文件:从读取和写入文件到观察目录和使用内存文件系统。Java有两个文件API。原始java.io.File API,自Java 1.0(1996)起可用。java.nio.file.Path从Java 1.7(2011)开始可用的较新API。File和Path API有什么区别?旧文件API用于大量旧项目,框架和库。尽管它已经很久了,但它并没有被弃用(并且可能永远不...

Global site tag (gtag.js) - Google Analytics