[关闭]
@ju1900 2017-08-18T13:55:48.000000Z 字数 2615 阅读 2347

Linux后台运行 (关掉终端继续让程序运行的方法)

linux


一、为什么要使程序在后台执行

我们计算的程序都是周期很长的,通常要几个小时甚至一个星期。我们用的环境是用putty远程连接到日本Linux服务器。所以使程序在后台跑有以下三个好处:

  1. 我们这边是否关机不影响日本那边的程序运行。(不会像以前那样,我们这网络一断开,或一关机,程序就断掉或找不到数据,跑了几天的程序只能重头再来,很是烦恼)
  2. 不影响计算效率
  3. 让程序在后台跑后,不会占据终端,我们可以用终端做别的事情。

二、怎么样使程序在后台执行

方法有很多,这里主要列举两种。假如我们有程序pso.cpp,通过编译后产生可执行文件pso,我们要使pso在linux服务器后台执行。当客户端关机后重新登入服务器后继续查看本来在终端输出的运行结果。(假设操作都在当前目录下)

  1. # ./pso > pso.file 2>&1 &

解释:将pso直接放在后台运行,并把终端输出存放在当前目录下的pso.file文件中。

当客户端关机后重新登陆服务器后,直接查看pso.file文件就可看执行结果(命令:#cat pso.file )。

  1. # nohup ./pso > pso.file 2>&1 &

解释:nohup就是不挂起的意思,将pso直接放在后台运行,并把终端输出存放在当前目录下的pso.file文件中。当客户端关机后重新登陆服务器后,直接查看pso.file

文件就可看执行结果(命令:#cat pso.file )。

三、常用任务管理命令

  1. # jobs //查看任务,返回任务编号n和进程号
  2. # bg [%]n //将编号为n的任务转后台运行
  3. # fg [%]n //将编号为n的任务转前台运行
  4. # ctrl+z //挂起当前任务
  5. # ctrl+c //结束当前任务

前后台切换:

在Linux中,如果要让进程在后台运行,一般情况下,我们在命令后面加上&即可,实际上,这样是将命令放入到一个作业队列中了:

  1. $ ./test.sh &
  2. [1] 17208
  3. $ jobs -l
  4. [1]+ 17208 Running ./test.sh &

对于已经在前台执行的命令,也可以重新放到后台执行,首先按ctrl+z暂停已经运行的进程,然后使用bg命令将停止的作业放到后台运行:

  1. $ ./test.sh
  2. [1]+ Stopped ./test.sh
  3. $ bg 1
  4. $ jobs -l
  5. [1]+ 22794 Running ./test.sh &

setsid

但是如上方到后台执行的进程,其父进程还是当前终端shell的进程,而一旦父进程退出,则会发送hangup信号给所有子进程,子进程收到hangup以后也会退出。如果我们要在退出shell的时候继续运行进程,则需要使用setsid将将父进程设为init进程(进程号为1)

  1. lte@ltepc42vm4:~$ ping 8.8.8.8
  2. PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.
  3. 64 bytes from 8.8.8.8: icmp_seq=1 ttl=42 time=31.9 ms
  4. ^Z
  5. [1]+ Stopped ping 8.8.8.8
  6. lte@ltepc42vm4:~$ echo $$
  7. 7673
  8. lte@ltepc42vm4:~$ !ps
  9. ps -ef | grep ping
  10. lte 7700 7673 0 13:54 pts/4 00:00:00 ping 8.8.8.8 # 父进程是7673
  11. lte 7702 7673 0 13:54 pts/4 00:00:00 grep --color=auto ping
  1. lte@ltepc42vm4:~$ setsid ping 8.8.8.8 > /dev/null
  2. lte@ltepc42vm4:~$ echo $$
  3. 7773
  4. lte@ltepc42vm4:~$ ps -ef | grep ping
  5. lte 7800 1 0 13:58 ? 00:00:00 ping 8.8.8.8 # 父进程是1
  6. lte 7802 7773 0 13:58 pts/2 00:00:00 grep --color=auto ping

上面的试验演示了使用nohup/setsid加上&使进程在后台运行,同时不受当前shell退出的影响。


disown

那么对于已经在后台运行的进程,该怎么办呢?可以使用disown命令:

  1. lte@ltepc42vm4:~$ ping 8.8.8.8 > /dev/null &
  2. [1] 7875
  3. lte@ltepc42vm4:~$ !ps
  4. ps -ef | grep ping
  5. lte 7875 7852 0 14:06 pts/4 00:00:00 ping 8.8.8.8
  6. lte 7877 7852 0 14:06 pts/4 00:00:00 grep --color=auto ping
  7. lte@ltepc42vm4:~$ echo $$
  8. 7852
  9. lte@ltepc42vm4:~$ jobs
  10. [1]+ Running ping 8.8.8.8 > /dev/null &
  11. lte@ltepc42vm4:~$ disown -h %1
  12. lte@ltepc42vm4:~$ !ps
  13. ps -ef | grep ping
  14. lte 7875 7852 0 14:06 pts/4 00:00:00 ping 8.8.8.8
  15. lte 7879 7852 0 14:07 pts/4 00:00:00 grep --color=auto ping
  1. lte@ltepc42vm4:~$ exit # 退出后查看进程
  2. lte@ltepc42vm4:~$ !ps
  3. ps -ef | grep ping
  4. lte 7875 1 0 14:06 ? 00:00:00 ping 8.8.8.8 # 这里的PID已经变成1, 不受shell退出影响
  5. lte 7937 7918 0 14:07 pts/2 00:00:00 grep --color=auto ping

子进程

另外还有一种方法,即使将进程在一个subshell中执行,其实这和setsid异曲同工。方法很简单,将命令用括号() 括起来即可:

  1. lte@ltepc42vm4:~$ (ping 8.8.8.8 > /dev/null &)
  2. lte@ltepc42vm4:~$ !ps
  3. ps -ef | grep ping
  4. lte 7943 1 0 14:09 pts/2 00:00:00 ping 8.8.8.8
  5. lte 7945 7918 0 14:09 pts/2 00:00:00 grep --color=auto ping

终止进程

终止当前后台运行的程序

  1. ps -ef | grep command
  2. kill -9 pid
  1. pkill command
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注