Contents

在 Linux 中使用NOHUP命令启动的程序

1. 概述

在本教程中,我们将研究获取在 Linux 中使用nohup 命令启动的程序列表的方法。我们将仔细研究一些可用于此目的的 Bash 实用程序。

2.问题描述

有时我们可能想要执行一个不受会话挂起或SIGHUP信号影响的程序。使用nohup命令执行程序可确保忽略挂断信号并继续运行进程

让我们使用nohup命令执行一个进程:

$ nohup sleep 50000
nohup: ignoring input and appending output to 'nohup.out'

现在,让我们启动另一个登录会话并使用pstree 命令检查进程树:

$ pstree -p
init(1)─┬─init(7)───init(8)───bash(9)───pstree(1140)
        ├─init(1121)───init(1122)───bash(1123)───sleep(1138)
        ├─{init}(5)
        └─{init}(6)

正如我们所见,PID 为 1138 的sleep 进程正在从 PID 为 1123 的 Bash shell 运行。现在让我们终止 PID 为 1123 的 shell 以挂起会话并再次验证进程:

$ kill -9 1123
$ pstree -p
init(1)─┬─init(7)───init(8)───bash(9)───pstree(1150)
        ├─init(1122)───sleep(1138)
        ├─{init}(5)
        └─{init}(6)

正如预期的那样,即使会话终止,睡眠进程也会继续运行。

在接下来的部分中,我们将研究过滤使用nohup命令启动的进程的方法。

3. 使用lsof命令

如果使用nohup命令执行进程的STDOUT是终端,则输出将记录在nohup.out文件中。我们可以使用此信息使用lsof 命令过滤进程:

$ lsof nohup.out
COMMAND  PID  USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
sleep   1138 shubh    1w   REG   8,16        0 3096 nohup.out
sleep   1138 shubh    2w   REG   8,16        0 3096 nohup.out

在这里,lsof命令列出了正在写入nohup.out文件的进程的 PID 和名称。正如预期的那样,我们的 PID 为 1138 的sleep进程出现在输出中。

**请务必注意,此技术仅适用于STDOUT重定向到终端的进程。**如果一个命令以nohup启动,但它的STDOUT被写入其他文件,那么上述解决方案将不会捕获该命令。让我们用一个例子来检查一下:

$ nohup sleep 500 > output.log &
[1] 43
$ nohup: ignoring input and redirecting stderr to stdout
$ lsof nohup.out
lsof: status error on nohup.out: No such file or directory

正如我们所看到的,由于nohup命令的输出被重定向到output.log而不是nohup.out ,因此lsof命令给出了错误。

4. 使用jobs命令

我们还可以使用jobs 命令从同一个 ssh 会话中检查是否有任何进程正在使用nohup运行:

$ sleep 7000 &
[1] 104
$ nohup sleep 500000 &
[2] 105
$ nohup: ignoring input and appending output to 'nohup.out'
$ jobs -l | grep nohup
[2]+ 105 Running nohup sleep 500000 &

请注意,此方法仅适用于同一个 ssh 会话,如果我们从不同的会话或 Bash shell 检查相同的进程,则不会显示nohup进程:

$ jobs -l | grep nohup
[2]+   105 Running                 nohup sleep 500000 &
$ bash
$ jobs -l
$ exit
exit
$ jobs -l | grep nohup
[2]+   105 Running                 nohup sleep 500000 &