阅读更多

0顶
0踩

操作系统

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

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

一. 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 条 请登录后发表评论

发表评论

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

相关推荐

  • JMP Call hook

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

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

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

  • windows 内存管理api学习笔记

    文章目录为什么使用虚拟内存分配虚拟内存Windows内存管理APIVirtualAllocVirtualProtectVirtualFreeC++代码 为什么使用虚拟内存 虚拟内存最适合用来管理大型对象或数据结构。 比如说,电子表格程序,有很多单元格,但是也许大多数的单元格是没有数据的,用不着分配空间。也许,你会想到用动态链表,但是访问又没有数组快。定义二维数组,就会浪费很多空间。 它的优点是同时具有数组的快速和链表的小空间的优点。 分配虚拟内存 如果你程序需要大块内存,你可以先保留内存,需要的时候再提交

  • 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核心编程_修改其它进程里的内存值+示例:修改游戏分数

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

  • Inline Hook 之(监视任意函数)

    前面已经写过两次inline hook的博文了,第一篇为:《C/C++ HOOK API(原理深入剖析之-LoadLibraryA)》,这篇博文的方法是通过修改任意函数的前面N个字节,实现跳转并进入到我们自定义的hook函数里,执行完毕我们的hook函数之后,再直接调用被hook的函数。第一篇的方法没有考虑多线程的情况,所以在多线程环境下会有问题。第二篇为:《Inline HOOK API 改进版(hot-patching)》,这篇的初衷是为了解决多线程的问题,因为这种方式是一直hook的,直到程序结束。

  • JMP、Hook

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

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

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

  • jmp address windows hook

    以下代码是sysnap早期发表的inlinehook ObReferenceObjectByHandle()的代码。大部分看懂了,但是有些看不懂,google也查了,qq群也问了。哪位高手有时间给科普下哈~ 可怜下偶们菜鸟吧。。。 __declspec(naked) T_ObReferenceObjectByHandle( IN HANDLE Handle, IN ACCESS_MASK

  • HOOK劫持自己

    #include <stdio.h> #include <stdlib.h> #include <Windows.h> #include "detours.h" #pragma comment(lib,"detours.lib")//包含库文件 int (*poldsystem)(const char * _Command) = system;...

  • 【干货】【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

  • Windows下 WINAPI HOOK实现方法 及 C++源码

    C++代码 及Demo // APIHook.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。 // #include <iostream> #include "string.h" #include "windows.h" using namespace std; struct StructAPIHook { string DLLName; string APIName; string DLLAnd...

  • Hook API 原理 解析

    1 什么是Hook API 简单的说,一个应用程序要调用一个API函数,例如CreateFileW,那么应用程序必须要知道函数的地址,才能调用它,我对Hook API的理解是,把这个函数地址替换为另一个函数MyCreateFileW的地址,那么每当程序调用CreateFileW时,就会调用MyCreateFileW 2 Hook API有什么用 在《Rootkits——W...

  • Hook API相关技术以及例子,Hook API的原理其实是通过核心函数强制修改原API的头部指针

    Hook API的原理其实是通过核心函数强制修改原API的头部指针,使其无条件跳转到自定义函数指针来实现的,如果学过汇编原理,其实就是jmp xxxlibrary HookComPort;uses  Windows,  SysUtils,  Classes;type  TCreateFile = function(lpFileName: PAnsiChar; dwDesiredAcce

Global site tag (gtag.js) - Google Analytics