3
votes

Comment utiliser la sortie en cours d'exécution de la console dans un autre programme

J'exécute un programme depuis la ligne de commande. Ce programme imprime certaines des statistiques de mon processeur (lien vers le programme si quelqu'un est intéressé: https://github.com/opcm / pcm ). Le programme ne se ferme pas. Il imprimera périodiquement des statistiques mises à jour dans le même terminal.

J'essaye d'utiliser ces statistiques que le programme récupère dans un autre programme que j'écris moi-même. Le programme que j'écris est juste censé représenter graphiquement certaines de ces statistiques CPU en fonction du temps en temps réel en python.

Je ne sais pas comment récupérer et utiliser les statistiques imprimées sur la console dans mon programme en temps réel. Je sais que je peux diriger la sortie vers un fichier texte plutôt que vers la console en tapant ./program.x> output.txt .

Ma première pensée est de pousser les statistiques produites dans un fichier texte, et de lire simultanément à partir de ce fichier texte dans mon programme. Mais cela ressemble à une méthode de force brute, et je ne suis pas sûr que cela fonctionnera.

Quelqu'un sait-il comment je peux utiliser la sortie en temps réel d'un programme dans un autre programme?


5 commentaires

Cela ressemble à un travail pour les tuyaux. Avez-vous envisagé des tuyaux pour votre cas d'utilisation?


@CharlesLandau Je n'ai jamais entendu parler ni utilisé de tuyaux. Je vais chercher ce qu'ils sont / comment ils sont utilisés.


Je posterai une réponse avec des tuyaux


Doublage indirect de: stackoverflow.com/questions/375427/... , car la sortie doit être lue à partir d'un sous-processus.


@Kingsley J'ai cherché des questions similaires mais je n'ai rien trouvé. Peut-être que le libellé de ma question était le problème et pourquoi je ne recevais pas de messages pertinents (ou simplement mon manque de connaissance des tuyaux). Mes excuses.


3 Réponses :


0
votes

Il semble que vous vouliez des tuyaux. Les tuyaux prennent la sortie standard d'un programme et la transmettent directement au suivant. L'exemple le plus simple auquel je puisse penser:

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

C'est facile à retenir car l'opérateur de tube ressemble un peu à un tube |

En savoir plus tuyaux: http: //web.cse.ohio-state .edu / ~ mamrak.1 / CIS762 / pipes_lab_notes.html

Edit: utiliser sys.stdin pour lire les tuyaux pour toujours est bien expliqué ici

Le modèle important à en tirer se trouve juste là:

ls | grep ".bin"


4 commentaires

Comment puis-je récupérer l'entrée dans mon programme à partir du tube qui reçoit la sortie de l'autre programme en python?


@ Mr.Mips la réponse courte est sys.stdin et je modifierai ma réponse ci-dessus


J'ai donc créé deux programmes à des fins de test. L'un imprime des nombres sur la console (appelée Runner) et le code de l'autre est exactement ce que vous m'avez donné sauf que j'ai ajouté une partie print (line) dans la boucle while (appelée Capture). Quand je lance Runner | Capture , où Runner et Capture sont les fichiers compilés à partir de mon code, cela ne fonctionnera pas et dit "Commandes Runner et Capture introuvables". Comment utiliser les tubes avec mes propres programmes compilés?


Ce serait une question distincte que vous pourriez publier sur SO, mais il semble que vos programmes ne soient pas dans PATH



0
votes

Vous pouvez créer quelque chose comme tail en python. Ceci est un exemple de code mais ne peut pas gérer si le fichier est supprimé.

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 commentaires

1
votes

Vous pouvez obtenir ce résultat de plusieurs manières.

Sur un système Unix, la plus simple, je crois, serait l'utilisation de tuyaux Disons que vous avez program1 (p1) qui génère des données et programme2 (p2) qui lit et utilise ces données.

Vous pouvez diriger la sortie de p1 vers p2 comme suggéré par @Charles Landau en utilisant | qui crée un tube entre le stdout et le stdin des 2 programmes

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

Si vous souhaitez également visualiser la sortie de p1, vous pouvez utiliser tee qui prend le stdin et le transfère vers le stdout et vers un programme

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()

Maintenant, cela ne fonctionnera que si vous avez l'intention de lancer p1 et p2 en même temps (à quel point un pense qu'il serait préférable d'en faire un seul programme). Une utilisation plus générique du tube serait pour p1 de créer un tube nommé (FIFO) et pour p2 de lire à partir de ce tube:

p1.py (serveur)

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)


3 commentaires

Voir J'utilise des outils PCM pour obtenir des statistiques de puissance du processeur en p1 et les miennes en p2. Je ne peux pas vraiment écrire un seul programme pour faire cela parce que je ne pense pas que je suis censé éditer le code source de PCM.


@ Mr.Mips Je vois que le code que vous utilisez propose également une API, ce qui signifie qu'il devrait être possible de l'importer en tant que module et d'utiliser ses appels de fonction pour écrire votre propre wrapper pour sa sortie.


@ Mr.Mips Une autre possibilité que vous pourriez essayer est d'utiliser quelque chose comme mkfifo name_of_fifo; ./pcm | tee name_of_fifo et ensuite utiliser le deuxième programme pour lire à partir de cette fifo. Le seul problème est que la sortie ne sera vidée que lorsque le tampon FIFO est plein. Un autre problème est que, selon le comportement du programme, la commande peut se bloquer jusqu'à ce que vous commenciez également à lire à partir du FIFO. (Par exemple mkfifo 1; python> 1 et dans shell2: tail -f 1 ne bloquera pas, mais commencera à imprimer la sortie seulement après que le FIFO aura été rempli avec quelque chose comme while 1: print ("HI"))