如何在另一个程序中使用控制台的运行输出

2024-06-02 07:18:41 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在从命令行运行一个程序。这个程序打印出我的一些CPU统计数据(如果有人感兴趣,可以链接到程序:https://github.com/opcm/pcm)。程序不退出。它会在同一终端中定期打印更新的统计数据。你知道吗

我正在尝试使用这些数据,这些数据是程序在我自己编写的另一个程序中检索到的。我正在编写的程序应该是用python实时绘制一些CPU统计数据与时间的关系图。你知道吗

我不知道如何在我的程序中检索和使用打印到控制台的统计数据。我知道我可以通过键入./program.x > output.txt将输出定向到文本文件而不是控制台。你知道吗

我的第一个想法是将输出的统计数据推送到一个文本文件中,同时在我的程序中读取该文本文件。但这感觉像是一个蛮力的方法,我不确定它是否有效。你知道吗

有人知道我如何在另一个程序中使用一个程序的实时输出吗?你知道吗


Tags: 数据命令行https程序githubcom终端链接
3条回答

您可以通过多种方式实现此结果。你知道吗

在unix系统上,我认为最简单的方法是使用管道 假设您有输出一些数据的program1(p1)和读取并使用这些数据的program2(p2)。你知道吗

您可以按照@Charles Landau的建议,使用|将p1的输出通过管道传输到p2,这将在2个程序的stdout和stdin之间创建一个管道

./p1 | p2

如果您还想可视化p1的输出,可以使用tee,它将stdin派生到stdout和程序

./p1 | tee p2

现在,只有当您打算同时启动p1和p2时(此时a认为最好将其作为一个单独的程序),这才有效。 管道的更通用用法是p1创建命名管道(FIFO),p2从该管道读取:

p1.py(服务器)

import os
from random import randint
import time

FIFO="/tmp/test_fifo"

if not os.path.exists(FIFO):
    os.mkfifo(FIFO)

pipe = os.open( FIFO, os.O_RDWR) #I use this to avoid the program hanging on this step.
                                 #When you open a FIFO, the behavior is blocking, meaning that the program will hang until both end (r/w) of the pipe are being used
f = os.fdopen( pipe, "w")        #Then i want a file object so i can flush it

while 1:
    # Do operation
    output = randint(0,999999)
    # Print output
    print(output)

    # Send output into pipe
    f.flush()
    f.write( str(output) + '\n')
    time.sleep(0.5)

f.close()
pipe.close()

os.unlink(FIFO)

p2.py(客户端)

import os
import sys

FIFO="/tmp/test_fifo"

if not os.path.exists(FIFO):
    exit()

f = open( FIFO, "r")

while 1:
    read_fifo = f.readline()
    print( read_fifo, end='')
    sys.stdout.flush()

您也可以使用shell在linux中对FIFO进行一些简单的测试

mkfifo 1
shell1: tail -f 1
shell2: echo "Hello!" > 1

以类似的方式,您可以使用TCP协议与2程序进行通信 有关此方法的详细信息,请参见pythonhttps://docs.python.org/3/library/socket.html

你可以在python中制作类似tail的东西。这是代码示例,但无法处理文件是否被删除。你知道吗

def tail_F(some_file):
    while True:
        try:
            for line in sh.tail("-f", some_file, _iter=True):
                yield line
                # do whatever with new line
        except sh.ErrorReturnCode_1:
            yield None

听起来你想要烟斗。管道获取程序的标准输出并将其直接传递给下一个程序。我能想到的最简单的例子是:

ls | grep ".bin"

很容易记住,因为管道操作符看起来像管道|

有关管道的详细信息:http://web.cse.ohio-state.edu/~mamrak.1/CIS762/pipes_lab_notes.html

编辑:使用sys.stdin来永久读取管道的解释很好here

重要的模式就在这里:

import sys
while True:
    line = sys.stdin.readline()
    # do something with line

相关问题 更多 >