Frage

Ich suche nach Möglichkeiten, Daten an die vorhandenen Prozesse zu schreiben STDIN aus externen Prozessen und fand eine ähnliche Frage Wie streamen Sie Daten in das Stdin eines Programms aus verschiedenen lokalen/entfernten Prozessen in Python? in Stackoverlow.

In diesem Thread sagt @Michael, dass wir wie unten Dateideskriptoren des vorhandenen Prozesses in Pfad erhalten können, und es ermöglicht, Daten unter Linux in sie zu schreiben.

/proc/$PID/fd/

Ich habe also ein einfaches Skript erstellt, das unten aufgeführt ist, um das Schreiben von Daten in das Skript zu testen STDIN (und TTY) aus dem externen Prozess.

#!/usr/bin/env python

import os, sys

def get_ttyname():
    for f in sys.stdin, sys.stdout, sys.stderr:
        if f.isatty():
            return os.ttyname(f.fileno())
    return None

if __name__ == "__main__":
    print("Try commands below")

    print("$ echo 'foobar' > {0}".format(get_ttyname()))
    print("$ echo 'foobar' > /proc/{0}/fd/0".format(os.getpid()))

    print("read :: [" + sys.stdin.readline() + "]")

Dieses Testskript zeigt Pfade von STDIN und TTY Und dann warten Sie darauf, dass einer es schreibt, es ist STDIN.

Ich habe dieses Skript gestartet und unten Nachrichten erhalten.

Try commands below
$ echo 'foobar' > /dev/pts/6
$ echo 'foobar' > /proc/3308/fd/0

Also habe ich den Befehl ausgeführt echo 'foobar' > /dev/pts/6 und echo 'foobar' > /proc/3308/fd/0 von einem anderen Terminal. Nach der Ausführung beider Befehle, Nachricht foobar wird zweimal auf dem Terminal angezeigt, auf dem das Testskript ausgeführt wird, aber das ist alles. Die Linie print("read :: [" + sys.stdin.readline() + "]") wurde nicht ausgeführt.

Gibt es Möglichkeiten, Daten aus externen Prozessen in die vorhandenen Prozesse zu schreiben STDIN (oder andere Dateideskriptoren), dh auf die Ausführung der Zeile aufzeigtprint("read :: [" + sys.stdin.readline() + "]") von anderen Prozessen?

War es hilfreich?

Lösung

Ihr Code funktioniert nicht.
/proc/pid/fd/0 ist ein Link zur /dev/pts/6 Datei.

$ echo 'foobar'>/dev/pts/6
$ echo 'foobar'>/proc/pid/fd/0

Da beide Befehle an das Terminal schreiben. Diese Eingabe geht an das Terminal und nicht an den Prozess.

Es wird funktionieren, wenn Stdin intial ein Rohr ist.
Zum Beispiel, test.py ist :

#!/usr/bin/python

import os, sys
if __name__ == "__main__":
    print("Try commands below")
    print("$ echo 'foobar' > /proc/{0}/fd/0".format(os.getpid()))
    while True:
        print("read :: [" + sys.stdin.readline() + "]")
        pass

Führen Sie dies als:

$ (while [ 1 ]; do sleep 1; done) | python test.py

Jetzt aus einem anderen Terminal etwas schreiben /proc/pid/fd/0 Und es wird kommen zu test.py

Andere Tipps

Ich möchte hier ein Beispiel lassen, das ich nützlich fand. Es ist eine leichte Modifikation des trugen Tricks oben, der auf meiner Maschine zeitweise fehlgeschlagen ist.

# pipe cat to your long running process
( cat ) | ./your_server &
server_pid=$!
# send an echo to your cat process that will close cat and in my hypothetical case the server too
echo "quit\n" > "/proc/$server_pid/fd/0"

Es war für mich hilfreich, weil ich aus bestimmten Gründen nicht verwenden konnte mkfifo, was perfekt für dieses Szenario ist.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top