linux后台执行

标签: linux 后台 | 发表时间:2011-10-31 15:19 | 作者:sylar_xj otter
出处:http://www.cnblogs.com/

 最近被很多人问,想退出secureCRT后,能够继续跑自己的进程,应该怎么实现,可以说这个方法不少,我就随便说说吧。

     为什么会有这样的需求?作为系统管理员,经常遇到这样的问题,用 telnet/ssh 登录了远程的 Linux 服务器,需要运行了一些耗时较长的任务,例如批量ping一些网段之类, 有时候却由于网络的不稳定导致任务中途失败,或者需要中途离开,总不会在等它结束吧,如果你退出SSH登陆的话,那么你的任务也会被终止了,岂不是白费精 力了?如何让命令或者任务在后台自己的运行,可以有很多方式实现,向大家都不陌生了,例如nohup,setsid和screen等等,我就简单说说吧。

    在我们通过SSH登陆服务器后,一般来说,所做的操作或者命令的输入都是属sshd下的shell的子进程,例如打开个SSH终端,输入ping www.163.com >>output.txt &,然后查看进程情况:
$ ps -ef|grep ping
sszheng 27491 27467 0 10:20 pts/0    00:00:00 ping www.163.com
sszheng 27535 27467 0 11:40 pts/0    00:00:00 grep ping

    很显然它是shell的子进程,命令由一个子shell在后台执行,当前shell(27467)立即取得控制等候用户输入,所以我的grep就可以使用了。后台命令和当前shell的执行是并行的,他们没有互相的依赖、等待关系,所以是异步的并行。 现在问题来了,如果ssh退出了,bash结束了,那么这个工作过程如何呢?后台执行的能否继续下去?

    这里涉及到两个问题,就是退出ssh后,在我们exit执行的shell时候,会不会向我们后台的jobs发送SIGHUP信号呢?
如果发送了
SIGHUP信号,那么所有该shell下运行的进程都会被终止,也就是所希望的后台执行没有实现。在shell的options中,有huponexit这个选项,意思就是退出shell时候,是否发送这个SIGHUP信号?
$ shopt 
cdable_vars     off
cdspell         off
checkhash       off
checkwinsize    off
cmdhist         on
dotglob         off
execfail        off
expand_aliases on
extdebug        off
extglob         off
extquote        on
failglob        off
force_fignore   on
gnu_errfmt      off
histappend      off
histreedit      off
histverify      off
hostcomplete    on
huponexit       off
interactive_comments    on
lithist         off
login_shell     on
mailwarn        off
no_empty_cmd_completion off
nocaseglob      off
nocasematch     off
nullglob        off
progcomp        on
promptvars      on
restricted_shell        off
shift_verbose   off
sourcepath      on
xpg_echo        off
    上面的默认选项中,huponexit       off,这个情况时候,当你退出shell时候,后台的程序还会继续运行,但是这个是全局选项,有时候我们往往希望退出shell后,shell发起的进 程相应结束了,而不是一直运行,因为有时候你可能开了很多子进程,没有时间去一一关闭吧??往往这个选项是建议打开的。

huponexit打开后,所以后台进行的jobs,在shell退出后就会相应退出了,但是针对我们特定的任务时候,我们可以对它进行单独操作,可以有下面集中方法。
1、nohup
nohup的用途就是让提交的命令忽略 hangup 信号,使用方法:
$nohup ping www.163.com & 
如果没有重定向输入和输出的话,标准输出和标准错误缺省会被重定向到 nohup.out 文件中。一般像示例一样,加上"&"来将命令同时放入后台运行,也可用">filename 2>&1"来更改缺省的重定向文件名。退出shell后,ping会继续运行,直到命令执行结束。
$ ps -ef |grep ping       
sszheng   5377 5311 0 16:51 pts/1    00:00:00 ping www.163.com
sszheng   5379 5311 0 16:51 pts/1    00:00:00 grep ping
退出shell后,重新登陆查看,ping进程依然在执行,只不过他的PPID变成了1,也就是被init所管理的孤儿进程了,稍后说一下孤儿进程。
$ ps -ef |grep ping
sszheng   5377     1 0 16:51 ?        00:00:00 ping www.163.com
sszheng   5389 5383 0 16:52 pts/0    00:00:00 grep ping


2、setsid

    nohup是通过忽略 HUP信号来使进程避免中途被中断,也可以用另一种方法,进程是不属于接受 HUP 信号的终端的shell子进程,那么自然也就不会受到 HUP 信号的影响了,真是白猫黑猫,抓到老鼠就是好猫,呵呵,废话多了。

    shell提供了setsid这个方法,

$setsid ping www.163.com & >>163.txt

$ ps -ef |grep ping

sszheng   5377     1 0 16:51 ?        00:00:00 ping www.163.com
sszheng   5395     1 0 16:56 ?        00:00:00 ping www.163.com
sszheng   5397 5383 0 16:57 pts/0    00:00:00 grep ping

大家应该注意到,上一个示例中,ping的父进程是5311,当它的父进程退出后,它才被init(PID=1)收养,而setsid直接把ping(pid=5395)给init了,那么就无所谓的shell退出影响了。

 

3、(&)

    再提一下关于subshell的使用,我们知道,将一个或多个命名包含在“()”中就能让这些命令在子 shell 中运行中,当我们将"&"也放入“()”内之后,我们就会发现所提交的作业并不在作业列表中,也就是说,是无法通过jobs来查看的。看看下面的进程id就知道了:

$(ping www.163.com &)

$ ps -ef |grep ping
sszheng   5377     1 0 16:51 ?        00:00:00 ping www.163.com
sszheng   5395     1 0 16:56 ?        00:00:00 ping www.163.com
sszheng   5401     1 0 17:03 pts/0    00:00:00 ping www.163.com
sszheng   5403 5383 0 17:03 pts/0    00:00:00 grep ping
可以看到,执行的5401的父进程是init了,这样子也可以达到忽略hup信号的目的了。

    说到这里,相信大家都略明白后台执行的方法了,简单说下原理:bash进程终止后,init 进程会接管父进程留下的这些“孤儿进程”,所以PPID是1了,孤儿进程不是僵尸进程,下面是他们的概念和区别

僵尸进程:一个子进程在其父进程还没有调用wait()或waitpid()的情况下退出。这个子进程就是僵尸进程。
孤儿进程:一个父进程退出,而它的一个或多个子进程还在运行,那么那些子进程将成为孤儿进程。孤儿进程将被init进程(进程号为1)所收养,并由init进程对它们完成状态收集工作。

简要说一下screen,它也是后台执行的一个重要工具,只不过它的功能远远不止后台执行而已。
    Screen是一个可以在多个进程之间多路复用一个物理终端的窗口管理器。Screen中有会话的概念,用户可以在一个screen会话中创建多个 screen窗口,在每一个screen窗口中就像操作一个真实的telnet/SSH连接窗口那样。在screen中创建一个新的窗口有这样几种方式:

1.直接在命令行键入screen命令

$ screen

    Screen将创建一个执行shell的全屏窗口。你可以执行任意shell程序,就像在ssh窗口中那样。在该窗口中键入exit退出该窗口,如果这是该screen会话的唯一窗口,该screen会话退出,否则screen自动切换到前一个窗口。

2.Screen命令后跟你要执行的程序。

$ screen vi test.sh

Screen创建一个执行vi test.sh的单窗口会话,退出vi将退出该窗口/会话。

3.以上两种方式都创建新的screen会话。我们还可以在一个已有screen会话中创建新的窗口。在当前screen窗口中键入C-a c,即Ctrl键+a键,之后再按下c键,screen 在该会话内生成一个新的窗口并切换到该窗口。

具体用法就不说了,既然不属于ssh管理,那何来接受退出信号呢?请注意会话这个概念。

    有兴趣的童鞋们,还可以看看disown相关的东东,这个东东的需求是:如果事先在命令前加上 nohup 或者 setsid 就可以避免 HUP 信号的影响。但是如果我们未加任何处理就已经提交了命令,该如何补救才能让它避免 HUP 信号的影响呢? 
我们可以用如下方式来达成我们的目的。

  • disown -h jobspec 来使某个作业忽略HUP信号。
  • disown -ah 来使所有的作业都忽略HUP信号。
  • disown -rh 来使正在运行的作业忽略HUP信号。


上面的方式的对象是作业,如果我们在运行命令时在结尾加了"&"来使它成为一个作业并在后台运行,我们可以通过jobs命令来得到所有作业的列表。但是如果并没有把当前命令作为作业来运行,如何才能得到它的作业号呢?答案就是用 CTRL-z(按住Ctrl键的同时按住z键)了!

CTRL-z 的用途就是将当前进程挂起(Suspend),然后我们就可以用jobs命令来查询它的作业号,再用bg jobspec来将它放入后台并继续运行。需要注意的是,如果挂起会影响当前进程的运行结果,就不推荐大家使用了。

 

就说到这了,说错了,请指点。

作者: sylar_xj 发表于 2011-10-31 15:19 原文链接

评论: 1 查看评论 发表评论


最新新闻:
· 《愤怒的小鸟》开发商今年将在华开设零售店(2011-10-31 18:06)
· 虚拟 还是 现实?(2011-10-31 18:03)
· 黑客利用社交工程技术发动攻击(2011-10-31 17:57)
· 神舟八号将在明天凌晨发射(2011-10-31 17:56)
· 看Siri如何革新911系统(2011-10-31 17:52)

编辑推荐:WP7交互特性浅析及APP设计探究

网站导航:博客园首页  我的园子  新闻  闪存  小组  博问  知识库

相关 [linux 后台] 推荐:

linux后台执行

- otter - 博客园-首页原创精华区
 最近被很多人问,想退出secureCRT后,能够继续跑自己的进程,应该怎么实现,可以说这个方法不少,我就随便说说吧.      为什么会有这样的需求. 作为系统管理员,经常遇到这样的问题,用 telnet/ssh 登录了远程的 Linux 服务器,需要运行了一些耗时较长的任务,例如批量ping一些网段之类, 有时候却由于网络的不稳定导致任务中途失败,或者需要中途离开,总不会在等它结束吧,如果你退出SSH登陆的话,那么你的任务也会被终止了,岂不是白费精 力了.

Javascript 里跑Linux

- rockmaple - Shellex's Blog
牛逼到暴的大拿 Fabrice Bellard,用Javascript实现了一个x86 PC 模拟器,然后成功在这个模拟器里面跑Linux(请用Firefox 4 / Google Chrome 11打开,Chome 12有BUG). 关于这个东西… 伊说 “I did it for fun“,大大啊大大啊….

Linux Ksplice,MySQL and Oracle

- Syn - DBA Notes
Oracle 在 7 月份收购了 Ksplice. 使用了 Ksplice 的 Linux 系统,为 Kernel 打补丁无需重启动,做系统维护的朋友应该明白这是一个杀手级特性. 现在该产品已经合并到 Oracle Linux 中. 目前已经有超过 700 家客户,超过 10 万套系统使用了 Ksplice (不知道国内是否已经有用户了.

linux makefile编写

- hl - C++博客-首页原创精华区
在讲述这个Makefile之前,还是让我们先来粗略地看一看Makefile的规则. target也就是一个目标文件,可以是Object File,也可以是执行文件. prerequisites就是,要生成那个target所需要的文件或是目标. command也就是make需要执行的命令. 这是一个文件的依赖关系,也就是说,target这一个或多个的目标文件依赖于prerequisites中的文件,其生成规则定义在 command中.

Linux下的VDSO

- 圣斌 - Adam's
VDSO(Virtual Dynamically-linked Shared Object)是个很有意思的东西, 它将内核态的调用映射到用户态的地址空间中, 使得调用开销更小, 路径更好.. 开销更小比较容易理解, 那么路径更好指的是什么呢. 拿x86下的系统调用举例, 传统的int 0×80有点慢, Intel和AMD分别实现了sysenter, sysexit和syscall, sysret, 即所谓的快速系统调用指令, 使用它们更快, 但是也带来了兼容性的问题.

Linux wget命令

- - CSDN博客推荐文章
wget是linux最常用的下载命令, 一般的使用方法是: wget + 空格 + 要下载文件的url路径. 例如: # wget  http://www.linuxsense.org/xxxx/xxx.tar.gz. 简单说一下-c参数, 这个也非常常见, 可以断点续传, 如果不小心终止了, 可以继续使用命令接着下载.

linux 小技巧

- - DBA Blog
2:如何限制用户的最小密码长度. 修改/etc/login.defs里面的PASS_MIN_LEN的值. 比如限制用户最小密码长度是8:. 3:如何使新用户首次登陆后强制修改密码. 4:更改Linux启动时用图形界面还是字符界面. 将id:5:initdefault: 其中5表示默认图形界面. 改id:3: initdefault: 3表示字符界面.

Linux iostat命令

- - CSDN博客系统运维推荐文章
iostat用于输出CPU和磁盘I/O相关的统计信息. . iostat [ -c | -d ] [ -k | -m ] [ -t ] [ -V ] [ -x ] [ device [. iostat各个参数说明:. -c 仅显示CPU统计信息.与-d选项互斥. -d 仅显示磁盘统计信息.与-c选项互斥.

Linux的架构

- - 博客园_首页
作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明. 我们以下图为基础,说明Linux的架构(architecture). (该图参考《 Advanced Programming in Unix Environment》). 最内层是我们的硬件,最外层是我们常用的各种应用,比如说使用firefox浏览器,打开evolution查看邮件,运行一个计算流体模型等等.

linux命令locate

- - 操作系统 - ITeye博客
    locate命令其实是"find -name"的另一种写法,但是要比后者快得多,原因在于它不搜索具体目录,而是搜索一个数据库(/var/lib/locatedb),这个数据库中含有本地所有文件信息. Linux系统自动创建这个数据库,并且每天自动更新一次,所以使用locate命令查不到最新变动过的文件.