linux - ¿Cómo escribir datos en el STDIN del proceso existente desde un proceso externo?
process file-descriptor (2)
Quiero dejar aquí un ejemplo que encontré útil. Es una ligera modificación del truco de verdad anterior que falló intermitentemente en mi máquina.
# 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"
Me fue útil porque, por razones particulares, no pude usar mkfifo
, lo cual es perfecto para este escenario.
Busco formas de escribir datos en el STDIN
del proceso existente desde procesos externos y encontré una pregunta similar ¿ Cómo se transfieren los datos al STDIN de un programa desde diferentes procesos locales / remotos en Python? en stackoverlow.
En ese hilo, @Michael dice que podemos obtener descriptores de archivos del proceso existente en la ruta como se muestra a continuación, y que podemos escribir datos en ellos en Linux.
/proc/$PID/fd/
Por lo tanto, he creado una secuencia de comandos simple que figura a continuación para probar la escritura de datos en STDIN
(y TTY
) de la secuencia de comandos desde un proceso externo.
#!/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() + "]")
Esta secuencia de comandos de prueba muestra las rutas de STDIN
y TTY
y luego, espera a que uno escriba STDIN
.
Puse en marcha este script y recibí los mensajes a continuación.
Try commands below
$ echo ''foobar'' > /dev/pts/6
$ echo ''foobar'' > /proc/3308/fd/0
Entonces, ejecuté el comando echo ''foobar'' > /dev/pts/6
y echo ''foobar'' > /proc/3308/fd/0
desde otra terminal. Después de la ejecución de ambos comandos, el mensaje foobar
se muestra dos veces en el terminal donde se ejecuta el script de prueba, pero eso es todo. La línea de print("read :: [" + sys.stdin.readline() + "]")
no se ejecutó.
¿Hay alguna forma de escribir datos de procesos externos en el STDIN
del proceso existente (u otros descriptores de archivo), es decir, invocar la ejecución de la línea de print("read :: [" + sys.stdin.readline() + "]")
desde otros procesos?
Tu código no funcionará.
/proc/pid/fd/0
es un enlace al archivo /dev/pts/6
.
$ echo ''foobar''> / dev / pts / 6
$ echo ''foobar''> / proc / pid / fd / 0
Dado que ambos comandos escriben en el terminal. Esta entrada va al terminal y no al proceso.
Funcionará si stdin inicialmente es una tubería.
Por ejemplo, test.py
es:
#!/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
Ejecutar esto como:
$ (while [ 1 ]; do sleep 1; done) | python test.py
Ahora, desde otro terminal, escriba algo en /proc/pid/fd/0
y vendrá a test.py