Как использовать запуск вывода из консоли в другой программе - PullRequest
0 голосов
/ 10 января 2019

Я запускаю программу из командной строки. Эта программа распечатывает некоторые статистические данные моего процессора (ссылка на программу, если кому-то интересно: https://github.com/opcm/pcm). Программа не завершается. Она будет периодически печатать обновленную статистику в том же терминале.

Я пытаюсь использовать эту статистику, которую программа извлекает в другой программе, которую я пишу сам. Программа, которую я пишу, должна отображать некоторую статистику процессора в зависимости от времени в реальном времени в python.

Я не уверен, как получить и использовать статистику, выводимую на консоль, в моей программе в режиме реального времени. Я знаю, что могу направить вывод в текстовый файл вместо консоли, набрав ./program.x > output.txt.

Моя первая мысль состоит в том, чтобы перенести выведенную статистику в текстовый файл и одновременно читать из этого текстового файла в моей программе. Но это похоже на метод грубой силы, и я не уверен, что это сработает.

Кто-нибудь знает, как я могу использовать вывод в реальном времени из одной программы в другую программу?

Ответы [ 3 ]

0 голосов
/ 10 января 2019

Вы можете сделать что-то вроде tail в python. Это пример кода, но он не может быть обработан, если файл удален.

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
0 голосов
/ 11 января 2019

Вы можете достичь этого результата несколькими способами.

В системе Unix, я полагаю, самым простым будет использование каналов Допустим, у вас есть программа1 (p1), которая выводит некоторые данные, и программа2 (p2), которая читает и использует эти данные.

Вы можете перенаправить вывод p1 в p2, как предложено @Charles Landau, используя |, который создает канал между stdout и stdin двух программ

./p1 | p2

Если вы хотите также визуализировать вывод p1, вы можете использовать tee, который принимает стандартный вывод и передает его на стандартный вывод и в программу

./p1 | tee p2

Теперь это будет работать, только если вы намереваетесь запускать p1 и p2 одновременно (в этот момент, как полагают, было бы лучше сделать это одной программой). Более общее использование канала было бы для 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()

Вы можете провести простое тестирование FIFO в linux, также используя оболочку

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

Аналогичным образом вы можете использовать протокол TCP для программы 2 для связи См. Python https://docs.python.org/3/library/socket.html для получения дополнительной информации об этом методе

0 голосов
/ 10 января 2019

Звучит так, будто ты хочешь трубы. Трубы получают стандартный вывод программы и передают ее непосредственно следующему. Абсолютно простой пример, который я могу представить:

ls | grep ".bin"

Это легко запомнить, потому что оператор трубы выглядит как труба |

Подробнее о трубах: http://web.cse.ohio -state.edu / ~ mamrak.1 / CIS762 / pipe_lab_notes.html

Редактировать: использование sys.stdin для чтения каналов всегда объясняется хорошо здесь

Важная схема, которую можно извлечь из этого, прямо здесь:

import sys
while True:
    line = sys.stdin.readline()
    # do something with line
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...