在 Linux 上将进程与父进程分离
对于 Linux 系统来说,从工作 shell 运行的每个程序都被视为一个进程。除 init
之外的每个进程都有其由 PPID(父进程 ID)标识的父进程。当您使用当前 shell 启动进程时,shell 本身将成为新启动进程的父进程。这种方法的问题在于,这可能并不总是令人满意,因为当父进程终止时,它的子进程也会随之终止。
这意味着关闭当前 shell 将终止其中的子进程。在某些情况下,这并不理想,因为它需要您保持终端或 SSH 会话处于活动状态,以避免停止其中运行的子进程。注销终端后,父 shell 将终止,从而终止从其派生的所有进程。在本教程中,我们将探索几种在 Linux 上将进程与其父进程分离的方法。
在本教程中您将学习:
如何使用
disown
和nohup
默认命令分离子进程如何将进程置于后台并将其调用到前台
如何使用
at
和screen
可安装命令分离子进程
通过将进程置于后台来分离进程
当您执行一个想要继续运行很长时间的命令时,问题是您当前的终端专用于该命令。您不能继续使用终端,也不能关闭它,因为这将结束当前正在运行的命令。
如果您正在运行命令,并且需要将其置于后台以释放终端,您可以按键盘上的 Ctrl + Z 来停止该进程。这是一个例子。
$ sleep 10000
^Z
[1]+ Stopped sleep 10000
要在后台查看作业列表,请使用 jobs
命令。
$ jobs -l
[1]+ 1650 Stopped sleep 10000
要将作业返回前台,我们可以使用 fg 命令。
$ fg
如果我们有多个已停止的作业,则需要使用百分号并指定作业 ID 以将相应的作业带回前台。
$ fg %1
太棒了,现在我们可以将进程放入后台,并在以后需要时将它们带回来。但是,如果我们希望命令在后台继续执行怎么办?为此,我们可以使用 bg
命令,后跟 & 符号和作业 ID。以下命令将使我们停止的作业恢复,同时将其保留在后台。
$ bg %1
[1]+ sleep 10000 &
现在我们可以看到该进程仍然在后台,但它显示的状态是“正在运行”而不是“已停止”。 ”
$ jobs -l
[1]+ 1650 Running sleep 10000 &
还有一件事需要记住。您无法关闭当前终端,否则这些后台作业将关闭。如果您需要关闭终端,并且不希望这些命令停止,那么您需要“否认”该作业。如果后台只有一项作业,则以下命令将起作用:
$ disown
如果您有多个,则需要指定作业 ID。
$ disown %1
执行 jobs
命令时,您将不再在作业表中看到该作业。现在可以安全地关闭终端,您的命令将继续运行。
$ jobs -l
您仍然可以使用 ps 命令来监视正在运行的命令。
$ ps aux | grep sleep
linuxco+ 1650 0.0 0.0 8084 524 pts/0 S 12:27 0:00 sleep 10000
如果要停止该命令运行,可以使用kill命令并指定进程ID。
$ kill 1650
现在我们已经了解了如何将正在运行的进程放入后台并在稍后调用它。但我们也可以选择一开始就在后台启动命令。您所需要做的就是在任何 Linux 命令末尾添加一个 & 符号。
$ sleep 10000 &
[1] 1900
和以前一样,我们可以使用 jobs
命令查看列出的作业。但这一次,作业已经在运行,我们不必在后台手动启动它。
$ jobs -l
[1]+ 1900 Running sleep 10000 &
使用 nohup 分离进程并保持其运行
我们已经在前面的示例中看到了如何使用 disown
命令来确保命令在关闭终端后继续运行。另一个选项是 nohup 命令。
nohup 告诉进程忽略它收到的任何 SIGHUP(挂断)信号。每当当前终端关闭时,SIGHUP 信号就会发送到后台作业。因此,我们可以在后台运行一个作业,关闭终端,但仍然看到它在后台运行。这是一个例子。
$ nohup sleep 10000 &
[1] 1908
nohup: ignoring input and appending output to 'nohup.out'
我们关闭了终端并重新打开它,然后运行以下命令,这表明该命令仍在运行。
$ ps aux | grep sleep
linuxco+ 1908 0.0 0.0 8084 524 ? S 13:05 0:00 sleep 10000
使用屏幕命令
到目前为止,我们已经介绍了在后台运行命令的默认 Linux 方法。但是,还可以使用额外的软件包。也许最流行的是 screen 命令。请参阅该链接以获取安装说明和详细使用说明。
我们可以将子进程附加到另一个进程,而不是将其附加到当前终端。将进程附加到“屏幕”会话将允许我们将其与当前终端分离,从而允许我们注销 SSH 会话或完全关闭终端,而无需停止正在运行的进程。
下面是它的工作原理:
运行
screen
命令来启动一个新的“屏幕”。 (可选)包含-S
选项为其命名。$ screen -S mycommand
在新的屏幕会话(创建时自动附加)中,执行您希望放入后台的命令或脚本。
$ /path/to/myscript.sh
按键盘上的
Ctrl + A
,然后按D
。这将分离屏幕,然后您可以关闭终端、注销 SSH 会话等,并且屏幕将持续存在。要查看屏幕列表,请使用此命令。$ screen -ls There is a screen on: 2741.mycommand (05/11/2022 01:13:24 PM) (Detached) 1 Socket in /run/screen/S-linuxconfig.
要重新连接到屏幕,请使用以下命令,并将下面的数字替换为您自己的进程 ID。
$ screen -r 2741
使用 at 命令分离进程
将进程与当前工作 shell 分离的一种更简单的方法可能是使用 at 命令(有关安装说明,请参阅链接的文章)。
下面的示例说明了如何运行作业(在本例中为 yes 命令),然后将该进程与当前工作 shell 分离。
$ at now
at> yes > /dev/null
at>
job 2 at Thu May 09 11:12:00 2022
在第一行,我们启动了带有时间参数 now
的 at
命令。接下来,我们输入我们想要运行的命令。最后,通过按 CTRL + D
组合键,我们发送 EOT
(文本结束)信号,表明我们已完成发出命令,作业将立即开始。使用 jobs 命令列出当前作业将不会产生任何输出,这意味着我们可以自由地脱离当前的 shell,而无需停止任何进程。
结束语
在本教程中,我们了解了如何在 Linux 系统上将进程与其父进程分离。分离子进程的主要动机是释放终端,以便可以关闭终端或用户可以从 SSH 或 telnet 会话中注销。在 Linux 上分离进程的方法有很多种,其中 screen
和 at
可能是最简单的,但默认情况下不可用。如果您不想安装额外的软件,disown
并在后台启动作业会很好。