Contents

在另一个bash会话中查看运行过程的输出

1. 概述

我们偶尔会运行命令或脚本,我们需要实时观察它们的输出。但是,该输出可能没有被定向到我们当前的终端。 在本教程中,我们将了解如何在另一个 Bash 会话中查看命令输出。我们将在不中断流程的情况下执行此操作。

2. 长时间运行脚本示例

想象一下,我们有一个名为Blogdemo_Categorization.sh的脚本,它根据主题将 Blogdemo 文章组织到目录中:

#!/bin/bash
grep -riH 'java' ~/articles/* >> Java
grep -riH 'kotln' ~/articles/* >> Kotlin
grep -riH 'scala' ~/articles/* >> Scala
grep -riH 'computer science' ~/articles/* >> Computer_Science
grep -riH 'linux' ~/articles/* >> Linux  

鉴于 Blogdemo 档案中的文章数量,这个过程可能会运行相当长的一段时间。运行脚本 ( $ ./Blogdemo_Categorization.sh ) 不会向我们的终端显示任何输出。 我们如何观察脚本的进度?

3. 在输出文件上使用tailcat

使用这种方法,我们将脚本的输出重定向到一个文件:

$ ./Blogdemo_Categorization.sh > file1

接下来,在新的 Bash 会话中,我们对该输出文件运行tail  命令:

$ tail -f file1

我们应该看到运行命令的输出流。 让我们尝试用cat替换 tail

$ cat file1

tail不同,** cat不会在所有数据到达时对所有数据进行流式传输,而是会打印出到目前为止的进度,然后结束**。当我们主要对**正在运行的进程输出的快照感兴趣时,cat很有用。**相反,tail -f会跟随正在运行的进程,直到我们按下 CTRL-C 来停止它。

4. 使用strace

在单独的 Bash 会话中,我们必须首先运行ps 以列出正在运行的进程:

$ ps -ef

从这里,我们找到正在运行的命令的进程 ID。这将位于命令语句记录的PID列下:

USER  PID   %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root  12754  0.0  0.0  48304  1344 pts/0    S+   17:12   0:00 Blogdemo_Categorization.sh

strace 然后跟踪系统调用和信号:

$ sudo strace -p12754 -s9999 -e write

使用此命令,我们将其*-p选项用于进程 ID。我们还使用-s9999选项无限扩展字符串大小输出。默认字符串大小为 32 个字符。最后,我们使用-e write选项来允许ASCII十六进制*字符。

这种方法比较常用,因为我们不需要对文件设置任何重定向,我们可以选择在进程启动后进行。

5. 使用nohup

nohup 使我们能够在没有挂断的情况下运行命令,并将输出发布到non-tty

$ sudo nohup Blogdemo_Categorization.sh

接下来,在新的 Bash 会话中,我们可以在nohup.out上使用tail 。这是一个包含命令语句输出的文件:

$ tail -f nohup.out

这会产生一个运行命令的输出流。 正如我们在第 3 节中观察到的,我们也可以用cat替换tail

6. 通过*/proc*观察输出

我们可以使用 Linux /proc目录查看输出。如果进程本身已经在其核心操作中重定向到文件,我们可以使用此方法:

$ ./Blogdemo_Categorization.sh > file1

接下来,我们使用tail命令显示文件增长时进程的输出。

$ sudo tail -f /proc/12754/fd/1

进程输出的恒定流将出现在我们的新 Bash 会话中。

此方法之所以有效,是因为/proc 文件夹托管子目录,其中包含每个正在运行的进程的虚拟流。子目录以进程 ID 命名。进程 ID 后面的*/fd文件夹是文件描述符。它**记录进程的流,即stdout*、stderr和其他输出**。stdout是我们感兴趣的输出流,即*/fd* 文件 1

和前面的部分一样,我们可以用cat替换tail

7. 使用watchBSD特有)

如果我们运行的是BSD平台,我们可以使用watch 命令来观察脚本的输出。因此,在一个会话中运行脚本后,在新会话中,我们可以运行watch

$ watch /dev/pts/0

/pts 代表伪终端从机。这是内核生成的一个文件夹,用于列出正在运行的进程的内容。在该*/dev/pts文件夹中,文件0*是具有脚本虚拟流的文件。