Come scrivere i dati sullo STDIN del processo esistente da un processo esterno?

Sono alla ricerca di modi per scrivere dati nello STDIN del processo esistente da processi esterni e ho trovato una domanda simile. Come si esegue lo streaming di dati nello STDIN di un programma da diversi processi locali / remoti in Python? in stackoverlow.

In quel thread, @Michael dice che possiamo ottenere i descrittori di file del processo esistente in un percorso come di seguito, e permesso di scrivere dati in essi su Linux.

 /proc/$PID/fd/ 

Quindi, ho creato un semplice script elencato di seguito per testare i dati di scrittura sullo STDIN (e TTY ) dello script da un processo esterno.

 #!/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() + "]") 

Questo script di test mostra i percorsi di STDIN e TTY e quindi aspetta che uno scriva STDIN .

Ho lanciato questo script e ho ricevuto messaggi di seguito.

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

    Quindi, ho eseguito il comando echo 'foobar' > /dev/pts/6 ed echo 'foobar' > /proc/3308/fd/0 dall’altro terminale. Dopo l’esecuzione di entrambi i comandi, il messaggio foobar viene visualizzato due volte sul terminale su cui è in esecuzione lo script di test, ma questo è tutto. La print("read :: [" + sys.stdin.readline() + "]") riga print("read :: [" + sys.stdin.readline() + "]") non è stata eseguita.

    Esistono modi per scrivere dati da processi esterni allo STDIN del processo esistente (o altri descrittori di file), ovvero richiamare l’esecuzione della print("read :: [" + sys.stdin.readline() + "]") riga print("read :: [" + sys.stdin.readline() + "]") da altri processi?

    Il tuo codice non funzionerà.
    /proc/pid/fd/0 è un collegamento al file /dev/pts/6 .

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

    Poiché entrambi i comandi scrivono sul terminale. Questo input va al terminale e non al processo.

    Funzionerà se stdin intially è una pipe.
    Ad esempio, test.py è:

     #!/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 

    Esegui come:

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

    Ora da un altro terminale scrivi qualcosa su /proc/pid/fd/0 e verrai su test.py

    Voglio lasciare qui un esempio che ho trovato utile. È una leggera modifica del trucco vero mentre sopra è fallito in modo intermittente sulla mia macchina.

     # 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" 

    Mi è stato d’aiuto perché per motivi particolari non ho potuto usare mkfifo , che è perfetto per questo scenario.