让进程在后台运行

通过ssh连上服务器之后,如果要运行一个耗时较长的任务,就会担心因为网络断开导致执行失败。这是因为通过ssh登陆系统之后,bash成为了sshd程序的一个子进程,所执行的任务则是bash的子进程。当网络断开后终端会收到一个HUP(hangup)信号,然后关闭终端的所有子进程,所以执行的任务也会被停止。

那么,要让任务不受网络断开的影响,便有两个思路:

1,让进程忽略HUP信号。

2,让进程不属于终端的子进程。

第一种思路可以使用nohup命令实现

# nohup ping baidu.com > /dev/null &
[1] 29876
# nohup: ignoring input and redirecting stderr to stdout
# ps -ef|grep ping|grep -v grep
root     29876 25203  0 16:53 pts/0    00:00:00 ping baidu.com

关闭当前终端,再重新打开一个终端,还会看到这个进程。

如果是已经开始执行的任务,那么就需要使用disown命令来忽略HUP信号

对于已经开始在前台运行的程序,需要先挂起,再使用bg让他在后台运行

# ping baidu.com > /dev/null
^Z
[1]+  Stopped                 ping baidu.com > /dev/null
# jobs
[1]+  Stopped                 ping baidu.com > /dev/null
# bg 1
[1]+ ping baidu.com > /dev/null &
# jobs
[1]+  Running                 ping baidu.com > /dev/null &
# disown -h %1
# ps -ef|grep ping|grep -v grep
root      3139  2892  0 17:17 pts/2    00:00:00 ping baidu.com
# logout
重新登陆之后进程还会在
# ps -ef|grep ping|grep -v grep
root      3139     1  0 17:17 ?        00:00:00 ping baidu.com

如果已经使用了&符号让任务在后台运行了

# ping baidu.com > /dev/null &
[1] 4339
# jobs
[1]+  Running                 ping baidu.com > /dev/null &
# disown -h %1
# logout
重新登陆之后
# ps -ef|grep ping|grep -v grep
root      4339     1  0 17:22 ?        00:00:00 ping baidu.com

如果有比较多的任务都需要忽略HUP信号,那就需要使用screen命令了,这个命令略强大,回头再说:)

 

第二种思路可以有两种实现

1,setsid,使用setsid命令可以让进程的ppid为1,即init进程

# setsid ping baidu.com > /dev/null 
# ps -ef|grep ping|grep -v grep
root     31225     1  0 16:59 ?        00:00:00 ping baidu.com

2,使用子shell也可以让进程的ppid为1

# (ping baidu.com > /dev/null &)
# ps -ef|grep ping |grep -v grep
root     32655     1  0 17:05 pts/0    00:00:00 ping baidu.com

 

参考:http://www.ibm.com/developerworks/cn/linux/l-cn-nohup/index.html

发表评论

电子邮件地址不会被公开。 必填项已用*标注