打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
linux中运行耗时的程序

linux中运行耗时的程序

分类: Linux 339人阅读 评论(0) 收藏 举报

目录(?)[+]

声明:
本blog欢迎转发,但请保留原作者信息:
新浪微博:@孔令贤HW
Blog地址:http://blog.csdn.net/lynn_kong
内容系本人学习、研究和总结,如有雷同,实属荣幸!


前几天微博中有人讲到要在linux中运行耗时的程序时,在断开SSH或网络中断时,如何保护程序不受影响(比如大文件的拷贝不中断):


因为自己以前使用过screen,但没有使用过nohup和setid,于是借此机会,学习一下,顺便做个记录,便于以后翻看。

1. 前言

首先有一个问题就是,我们平常使用ssh登录服务器运行一个耗时程序,程序未运行完,我们断开ssh,此时程序也会中断。这是因为进程收到了SIGHUP信号而退出。举个例子:
1. 打开两个ssh终端窗口,在其中一个运行top命令,在另一个窗口可以查看:

2. 关闭第一个SSH窗口,在另一个窗口中可以看到top也被杀掉了。


那么如何可以解决这个问题?有两种途径:要么让进程忽略 HUP 信号,要么让进程运行在新的会话里从而成为不属于此终端的子进程。

2. nohup/setsid

对于单个命令的长时间运行,可以使用如下两种方法:

2.1 nohup

nohup 的用途就是让提交的命令忽略HUG信号。nohup使用非常简单,如果程序的标准输出/标准错误是终端,nohup默认将其重定向到nohup.out文件。值得注意的是nohup命令只是使程序忽略SIGHUP信号,一般我们可在结尾加上"&"来将命令同时放入后台运行。例如:
  1. root@openstack:~# nohup ping www.baidu.com &  
  2. [1] 20532  
  3. root@openstack:~# nohup: ignoring input and appending output to `nohup.out'  
可以把当前窗口关闭,新开一个终端窗口,运行如下命令查看:
  1. root@openstack:~# ps -ef | grep ping   
  2. root     20532 13977  0 00:56 pts/0    00:00:00 ping www.baidu.com  
  3. root     22449 20000  0 00:57 pts/1    00:00:00 grep --color=auto ping  
可以看到,程序依然在运行。

2.2 setid

nohup 无疑能通过忽略 HUP 信号来使进程避免中途被中断,但如果一个进程不属于接受 HUP 信号的终端的子进程,那么自然也就不会受到 HUP 信号的影响,此时就可以使用setid达到同样的目的。setid的使用与nohup相似,只需在要处理的命令前加上 setsid 即可,但这里需要指出的是,setid运行的进程的父进程是init(PPID=1),而不是当前终端的进程 ID.

3. disown

前面已经讲了在命令前加上 nohup 或者 setsid 就可以避免 HUP 信号的影响,但如果程序已经执行,而忘了加nohup或setid,该如何补救才能让它避免 HUP 信号的影响呢?
  1. root@openstack:~# ping www.baidu.com >temp.txt &  
  2. [1] 20154  
  3. root@openstack:~# jobs  
  4. [1]+  Running                 ping www.baidu.com > temp.txt &  
  5. root@openstack:~# disown -h %1  
  6. root@openstack:~# ps -ef | grep ping  
  7. root     20154 14260  0 01:14 pts/0    00:00:00 ping www.baidu.com  
  8. root     21336 14260  0 01:14 pts/0    00:00:00 grep --color=auto ping  
  9. root@openstack:~# logout  
  10. (上面的ping命令在我的ubuntu虚拟机上貌似不受HUP信号的影响,因此上述的命令仅仅是为了演示)  
如果不是后台运行的命令,则可以先ctrl+z将程序暂停,然后bg命令使其在后台运行,之后操作与上述一样。

4. screen

sceen我想大家基本上都用过,就不细讲了,只举例说明。
1. 打开一个终端窗口。输入screen新建会话(也可以screen –S name指定会话的名称,便于识别)
root@openstack:~# screen -S kong
之后就会进入一个全新的shell窗口。
2. 可以ctrl+a,A为窗口命名,这里我命名为"window1"

3. 在"window1"中,ctrl+a,c,再新建一个窗口
4. ctrl+a,A, 将新建的窗口命名为"window2"
5. ctrl+a,w,显示"kong"会话中的所有窗口

6. ctrl+a,0,切换到"window1",这里也可以使用ctrl+a,n或ctrl+a,p来进行上下切换。
7. 在"window1"中执行ping www.baidu.com命令
  1. root@openstack:~# ping www.baidu.com  
  2. PING www.a.shifen.com (119.75.217.56) 56(84) bytes of data.  
  3. 64 bytes from 119.75.217.56: icmp_req=1 ttl=128 time=29.5 ms  
  4. 64 bytes from 119.75.217.56: icmp_req=2 ttl=128 time=23.4 ms  
  5. 64 bytes from 119.75.217.56: icmp_req=3 ttl=128 time=23.5 ms  
  6. ……  
8. ctrl+a,1,切换到"window2",随意做一些操作。然后ctrl+a,0切换到"window1",ping命令仍在执行。
9. 关闭xshell,重新打开,登录服务器。键入screen -ls可以查看到所有的screen会话。
  1. root@openstack:~# screen -ls  
  2. There is a screen on:  
  3. 7166.kong (2013年05月05日 01时29分08秒) (Detached)  
  4. 1 Socket in /var/run/screen/S-root.  
10. screen -r 7166,进入会话,会发现重新进入了之前退出时的界面。
11. ctrl+a,d,保留程序执行状态,断开当前的会话,此时键入screen -ls与前面看到的输出一样。
12. 在一个screen窗口中键入exit或ctrl+a,k,会退出当前窗口,如果会话中只有一个窗口,那么会退出整个screen会话。

这里简单解释一下为什么使用screen不会中断程序的执行,screen 是 init(PID为1)的子进程。那么当 ssh 断开连接时,HUP 信号自然不会影响到 screen 下面的子进程了。
本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
Linux 技巧:让进程在后台可靠运行的几种方法
nohup、setsid、&和disown
这些进程的后台可靠运行命令你都知道了吗
UNIX进程组,会话和作业控制
ECSHOP
云计算管理平台之OpenStack启动虚拟机实例
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服