Skip to content

了解 Linux 中的前台和后台进程

作为一名 Linux 系统管理员,你可能有时候想让某些进程在后台运行,这样你就可以继续在终端里干别的事,而不用等着后台进程跑完。Linux 系统支持同时运行多个进程,并且可以让程序在前台或后台执行。

在 Linux 系统上把命令或进程放到后台运行是个很常见的操作,尤其是当你想释放终端,或者从 SSH 会话断开连接时。特别是一些需要跑很久的命令,比如监听事件或完成复杂任务的命令,这种需求就更明显。

Linux 提供了几种方法来运行后台进程。这篇教程会介绍几种常用方法,通过示例教你怎么用,还会讲讲如何把进程从前台移到后台,或者反过来。

在这篇教程分为四个部分:

  • 如何把正在运行的命令放到后台
  • 如何直接在后台启动一个命令
  • 如何关闭终端但让后台任务继续运行
  • 如何使用 screen 命令

把正在运行的命令放到后台

当你运行一个需要长时间执行的命令时,问题在于你的终端会被这个命令“霸占”。你没法继续用这个终端干别的事,也不能关闭终端,因为一关命令就停了。

如果有个命令正在跑,你想把它丢到后台去释放终端,可以按键盘上的 Ctrl + Z 来暂停这个进程。来看个例子:

bash
$ sleep 10000
^Z
[1]+  Stopped                 sleep 10000

想看看有哪些后台任务,可以用 jobs 命令:

bash
$ jobs -l
[1]+  1650 Stopped                 sleep 10000

要把一个暂停的任务拉回前台,可以用 fg 命令:

bash
$ fg

如果有多个暂停的任务,你得用百分号加上任务 ID 来指定哪个任务要拉回前台:

bash
$ fg %1

好了,现在我们知道怎么把进程丢到后台,也知道怎么把它拉回来。但如果我们想让这个命令在后台继续跑怎么办?可以用 bg 命令,后面加上百分号和任务 ID。下面的命令会让暂停的任务继续运行,同时保持在后台:

bash
$ bg %1
[1]+ sleep 10000 &

再看看任务状态,可以看到进程还在后台,但状态从“暂停”变成了“运行”:

bash
$ jobs -l
[1]+  1650 Running                 sleep 10000 &

不过得注意一件事:你不能直接关闭当前终端,不然这些后台任务也会跟着停掉。如果真想关终端又不让任务停,可以用 disown 命令“脱离”这个任务。如果后台只有一个任务,下面这个命令就够了:

bash
$ disown

如果有多个任务,就得指定任务 ID:

bash
$ disown %1

这时候再用 jobs 命令,你会发现这个任务已经不在列表里了。现在可以放心关闭终端,命令还会继续跑:

bash
$ jobs -l

你可以用 ps 命令继续监控这个运行中的命令:

bash
$ ps aux | grep sleep
linuxco+    1650  0.0  0.0   8084   524 pts/0    S    12:27   0:00 sleep 10000

如果想停掉这个命令,可以用 kill 命令加上进程 ID:

bash
$ kill 1650

直接在后台启动命令

前面讲了怎么把正在跑的进程丢到后台,但其实你也可以一开始就让命令在后台运行。只需要在命令后面加个 & 符号就行:

bash
$ sleep 10000 &
[1] 1900

跟之前一样,用 jobs 命令可以看到这个任务,而且它已经是在运行状态了,不需要我们手动丢到后台:

bash
$ jobs -l
[1]+  1900 Running                 sleep 10000 &

关闭终端但让后台任务继续运行

之前我们已经看到可以用 disown 命令让任务在终端关闭后继续跑。还有一个方法是用 nohup 命令。

nohup 能让进程忽略 SIGHUP(挂起)信号。SIGHUP 信号会在终端关闭时发送给后台任务。所以用了 nohup,你就可以把任务丢到后台,关掉终端,任务也不会停。来看个例子:

bash
$ nohup sleep 10000 &
[1] 1908
nohup: ignoring input and appending output to 'nohup.out'

关掉终端再重新打开,然后运行下面这个命令,可以看到任务还在跑:

bash
$ ps aux | grep sleep
linuxco+    1908  0.0  0.0   8084   524 ?        S    13:05   0:00 sleep 10000

使用 screen 命令

到目前为止,我们讲的都是 Linux 默认的后台运行方法。不过还有一些额外的工具可以用,最常用的可能是 screen 命令。

具体安装和详细用法可以参考相关链接,这里简单讲讲怎么用:

  1. 运行 screen 命令启动一个新的“屏幕”。可以加 -S 选项给它取个名字:

    bash
    $ screen -S mycommand
  2. 在新的 screen 会话里,运行你想丢到后台的命令或脚本:

    bash
    $ /path/to/myscript.sh
  3. 按键盘上的 Ctrl + A,然后按 D,这样会“脱离”这个 screen。然后你可以关闭终端、退出 SSH 会话,screen 里的任务还会继续跑。想看看有哪些 screen,可以用这个命令:

    bash
    $ screen -ls
    There is a screen on:
    2741.mycommand	(04/08/2021 01:13:24 PM)	(Detached)
    1 Socket in /run/screen/S-linuxconfig.
  4. 要重新连接到一个 screen,用下面这个命令,把下面的数字换成你自己的进程 ID:

    bash
    $ screen -r 2741