Home » ops » 让进程在后台运行
让进程在后台运行

最近搭建了一个分布式的文件系统,替换以前的云存储需要导很多数据,金大侠在他的机器上跑的脚本,但是他是在前台跑的,后来他电脑待机了,结果可想而知。 因为通过ssh连到服务器上跑脚本,默认都是sshd的子进程(通过 pstree 可以看到),当ssh断开之后,这些子进程都会接到hup信号而终止。所以跑脚本就一定要后台去跑。 在linux上让进程在后台运行的方式也挺多的。

nohup/setsid/&

如果只是临时有一个命令需要长时间运行,什么方法能最简便的保证它在后台稳定运行呢?

我们知道,当用户注销(logout)或者网络断开时,终端会收到 HUP(hangup)信号从而关闭其所有子进程。 因此,我们的解决办法就有两种途径:要么让进程忽略 HUP 信号,要么让进程运行在新的会话里从而成为不属于此终端的子进程。

比如 nohup SOME_COMMAND & 就是在后台运行命令,并且禁掉hup信号。标准输出和错误输出都在nohup.out文件中,也可用">filename 2>&1"来更改缺省的重定向文件名。

命令 setsid SOME_COMMAND 让当前进程不再是终端的子进程,所以也可以稳定的在后台运行。

命令 (SOME_COMMAND &) 也是通过让进程不再是终端的子进程而不受当前终端的hup信号影响。

disown

如果命令已经在跑着了,那么想让它在后台去安稳运行怎么办呢?

那就可以用 disown 命令。

需要注意的是,当使用过 disown 之后,会将把目标作业从作业列表中移除,我们将不能再使用jobs来查看它,但是依然能够用ps -ef查找到它。 如果进程实在前台运行的,那就可以先通过Ctrl-z将进程suspend,然后通过 jobs 命令查看它的作业号,然后在通过 bg 命令扔到后台运行,最后在 disown 一下。

screen

当然,最好的跑脚本的方式是通过 screen 命令,就像东颖说得,用screen跑脚本是程序员的基本素质。

简单的说,screen 提供了 ANSI/VT100 的终端模拟器,使它能够在一个真实终端下运行多个全屏的伪终端。

基本命令为:

通过screen执行的进程,它的父进程是screen而不是sshd,所以当ssh断开时也不会有影响。