Por lo que sé, si escribo lo siguiente ...
python -i
... el intérprete de python ahora leerá desde stdin, comportándose (obviamente) así:
>>> print "Hello"
Hello
Espero que haga lo mismo si hago esto:
echo 'print "Hello"' > /proc/$(pidof python)/fd/0
Pero esta es la salida (siendo una línea vacía real):
>>> print "Hello"
<empyline>
Esto para mí parece, simplemente tomó el print "Hello"\n
y se lo escribió stdout
, pero no lo interpretó. ¿Por qué eso no funciona y qué tendría que hacer para que funcione?
proc
file-descriptors
Sheppy
fuente
fuente
Respuestas:
Enviar comentarios a intérpretes / intérpretes de esta manera es muy propenso a problemas y es muy difícil que funcione de manera confiable.
La forma correcta es usar sockets, es por eso que se inventaron, puede hacerlo en la línea de comandos usando
ncat
nc
osocat
para vincular un proceso de Python a un socket simple. O escriba una aplicación simple de Python que se una al puerto y escuche los comandos para interpretar en un socket.los sockets pueden ser locales y no estar expuestos a ninguna interfaz web.
El problema es que si comienzas
python
desde la línea de comando, normalmente está conectado a tu shell que está conectado a una terminal, de hecho podemos verasí que cuando escribes en
stdin
python, en realidad estás escribiendo en elpty
terminal psuedo, que es un dispositivo kernel, no un simple archivo. Utilizaioctl
noread
ywrite
, por lo verá una salida en la pantalla, pero no va a ser enviado al proceso generado (python
)Una forma de replicar lo que está intentando es con un
fifo
onamed pipe
.También puede usar
screen
solo para entradafuente
sleep 300 > python_i.pipe &
), el otro lado no se cerrará ypython
continuará aceptando comandos por la tubería. No hay EOF como tal enviado porecho
.|
tuberías, sin embargo, ¿correcto?echo something > fifo
causaría un EOF que detendría muchas aplicaciones. Sinsleep infinity > fifo
embargo, la solución no cruzó mi mitad, ¡gracias!python -i <> fifo
lo que también evitará el EOFEl acceso no accede al descriptor de archivo 0 del PID de proceso , accede al archivo que PID ha abierto en el descriptor de archivo 0. Esta es una distinción sutil, pero es importante. Un descriptor de archivo es una conexión que un proceso tiene con un archivo. Escribir en un descriptor de archivo escribe en el archivo independientemente de cómo se haya abierto el archivo.
/proc/PID/fd/0
Si es un archivo normal, escribir en él modifica el archivo. Los datos no son necesariamente lo que el proceso leerá a continuación: depende de la posición adjunta al descriptor de archivo que el proceso está usando para leer el archivo. Cuando se abre un proceso , obtiene el mismo archivo que el otro proceso, pero las posiciones del archivo son independientes.
/proc/PID/fd/0
/proc/PID/fd/0
Si es una tubería, entonces escribir en ella agrega los datos al búfer de la tubería. En ese caso, el proceso que está leyendo desde la tubería leerá los datos.
/proc/PID/fd/0
Si es un terminal, entonces escribir en él genera los datos en un terminal. Un archivo de terminal es bidireccional: escribir en él genera los datos, es decir, el terminal muestra el texto; la lectura desde un terminal ingresa los datos, es decir, el terminal transmite la entrada del usuario.
/proc/PID/fd/0
Python está leyendo y escribiendo en la terminal. Cuando corres
echo 'print "Hello"' > /proc/$(pidof python)/fd/0
, estás escribiendoprint "Hello"
en la terminal. El terminal se muestraprint "Hello"
como se indica. El proceso de Python no ve nada, todavía está esperando la entrada.Si desea alimentar la entrada al proceso de Python, debe obtener el terminal para hacerlo. Vea la respuesta de crasic para saber cómo hacerlo.
fuente
Partiendo de lo que dijo Gilles , si queremos escribir en el stdin de un proceso que está conectado a una terminal, en realidad necesitamos enviar la información a la terminal. Sin embargo, debido a que un terminal sirve como una forma de entrada y salida, al escribir en él el terminal no tiene forma de saber que desea escribir en un proceso que se ejecuta dentro de él en lugar de la "pantalla".
Sin embargo, Linux tiene una forma no posix de simular la entrada del usuario a través de una solicitud ioctl llamada
TIOCSTI
(Control de E / S de terminal - Simular entrada de terminal) que nos permite enviar caracteres a una terminal como si los hubiera escrito un usuario.Solo soy superficialmente consciente de cómo funciona esto, pero en base a esta respuesta, debería ser posible hacer esto con algo parecido a
Algunos recursos externos:
http://man7.org/linux/man-pages/man2/ioctl.2.html
http://man7.org/linux/man-pages/man2/ioctl_tty.2.html
fuente