如何在执行过程中捕获终端输出?

如何在执行过程中捕获终端输出?

我尝试使用 Byte Commander 对该问题的回答中提到的所有命令这里但程序未完成时它们就不起作用。

我正在运行类似“python script.py”的 python 脚本,并尝试将 Byte Commander 答案中的“command”替换为“python script.py”,但是终端输出不再显示在终端中,并且只有在 python 脚本完成的情况下才会写入文件 output.txt(实际上我发现它在执行过程中会分成大块,但不是我需要的逐行)。我相信这可能是因为 python 脚本在另一个 shell 中调用了另一个非 python 程序(它调用了一个名为 gmesh 的有限元包)。代码需要很长时间(几个小时)才能完成,我希望能够在执行过程中看到写入文件的输出,这样我就可以看到它的进度和终端输出的样子,即使程序中途崩溃了。我该怎么做?

我添加了一个视频演示该问题。当程序运行时没有捕获信息,信息会逐行出现。当我尝试捕获输出时,它会以块的形式出现,当这些块需要几个小时并且在此过程中崩溃时,我无法获得有关它在哪里崩溃的信息。

答案1

您可以按照以下示例进行操作。

myscript.py假设我们有一个名为这样的脚本:

import time
for x in range(0, 33):
   print("hello", x, flush=True)
   time.sleep(1)

那么如果我们像这样运行它:

python3 myscript.py > mylog.txt

它会挂在那里直到完成,所以我们在运行时不会看到输出。

为了能够在运行时看到输出,我们可以这样做:

python3 myscript.py > mylog.txt &

其中 & 符号表示终端不会挂起,我们可以在终端运行时给出更多命令。然后,我们可以这样做来查看 myscript.sh 写入日志文件时日志文件的内容:

tail -f mylog.txt

(另一种可能性是打开一个单独的终端窗口并tail -f mylog.txt从那里执行。)

请注意,要使其正常工作,行flush=True的部分print很重要,否则flush=True文件内容只有在程序完成后才会显示。

如果输出是由 Python 脚本中的其他程序生成的,则可以尝试在调用其他程序后在 Python 代码中添加import sys并执行。请参阅sys.stdout.flush()https://stackoverflow.com/a/230774/6708867

答案2

import subprocess,shlex
command = 'python mesh.py'
workingdirectory = 'C:users/Account/Desktop'
try:
    process = subprocess.Popen(shlex.split(command), stdout=subprocess.PIPE,
                                     stderr=subprocess.PIPE, shell=True, cwd=workingdirectory)

    stdout, stderr = process.communicate()

     if stderr.decode('utf-8') == "":
        with open(outputlog.txt, 'w'):
             file.write(stdout.decode('utf-8'))
     else:
          with open(errorlog.txt,'w') as file:
              file.write(stderr.decode('utf-8'))

在工作目录中创建2个名为outputlog和errorlog的空文本文件。

使用 Shlex 构建你的命令,使用 Popen 构建 IPC 命令。

答案3

如果您希望以字符串形式获取输出。请尝试按照以下步骤操作:

Var = os.popen(command).read()

该模块打开一个到命令的管道;然后您可以像记录任何其他内容一样记录它。

相关内容