2011-05-10 19 views
15

en cuenta la situación siguiente:Prevenir FIFO de cierre/reutilización cerrado FIFO

un FIFO nombrado se crea test. En una ventana de terminal (A) ejecuto cat <test y en otra (B) cat >test. Ahora es posible escribir en la ventana B y obtener la salida en la ventana A. También es posible finalizar el proceso A y reiniciarlo y aún así poder utilizar esta configuración como se sospecha. Sin embargo, si finaliza el proceso en la ventana B, B (hasta donde yo sé) enviará un EOF a través del FIFO para procesar A y finalizarlo también.

De hecho, si ejecuta un proceso que no termina en EOF, aún no podrá usar su FIFO que redireccionó al proceso. Lo cual creo es porque este FIFO se considera cerrado.

¿Hay alguna forma de evitar este problema?

La razón por la que me encontré con este problema es porque me gustaría enviar comandos a mi servidor de Minecraft ejecutándose en una sesión de pantalla. Por ejemplo: echo "command" >FIFO_to_server. Esto es probablemente posible haciendo uso de la pantalla por sí mismo, pero no estoy muy cómodo con la pantalla. Creo que una solución que utiliza solo tuberías sería más simple y más limpia.

Respuesta

26

A está leyendo de un archivo. Cuando llega al final del archivo, deja de leer. Este es un comportamiento normal, incluso si el archivo resulta ser un fifo. Ahora tiene cuatro enfoques.

  1. Cambie el código del lector para que siga leyendo después del final del archivo. Eso significa que el archivo de entrada es infinito, y llegar al final del archivo es solo una ilusión. No es práctico para ti, porque tendrías que cambiar el código del servidor de Minecraft.
  2. Aplicar la filosofía de Unix. Usted tiene un escritor y un lector que no están de acuerdo con el protocolo, por lo que interpone una herramienta que los conecta. Da la casualidad que existe una herramienta de este tipo en la caja de herramientas de Unix: tail -f. tail -f sigue leyendo desde su archivo de entrada incluso después de ver el final del archivo. Haga que todos sus clientes se comunican con el tubo, y se conectan al servidor tail -f Minecraft:

    tail -n +1 -f client_pipe | minecraft_server & 
    
  3. As mentioned by jilles, utilizar un truco: Tubos admiten varios escritores, y sólo se convierten cerrada cuando el último escritor desaparece. Así que asegúrese de que haya un cliente que nunca se vaya.

    while true; do sleep 999999999; done >client_pipe & 
    
  4. El problema es que el servidor está diseñado fundamentalmente para manejar un solo cliente. Para manejar múltiples clientes, debe cambiar a usar un socket. Piense en sockets como "meta-pipes": la conexión a un socket crea una tubería, y una vez que el cliente se desconecta, esa tubería en particular se cierra, pero el servidor puede aceptar más conexiones. Este es el enfoque limpio, ya que también asegura que no habrá datos confusos si dos clientes se conectan al mismo tiempo (usando tuberías, sus comandos podrían estar intercalados). Sin embargo, requiere cambiar el servidor de Minecraft.

+0

Desafortunadamente 'tail' espera EOF para que no pase el contenido de la tubería línea por línea. – pabouk

+2

@pabouk Gracias por señalar este error: 'tail -n 1 -f' omitiría la entrada disponible antes de que comenzara o se pusiera a disposición más rápido de lo que podría leer.Quería escribir 'tail -n +1 -f', que comienza a emitirse directamente. – Gilles

+2

Gracias. Lo he intentado antes, pero '-n + 1' no funcionó como esperaba. Ahora, como confirmó que esta es la manera correcta, examiné el problema más a fondo y me di cuenta de que el problema está en el almacenamiento en búfer de bloques (en lugar del búfer de línea predeterminado) de stdout de 'tail'. La solución para la tubería línea por línea: 'stdbuf -oL tail -n +1 -f client_pipe | command' – pabouk

6

Inicie un proceso que mantenga el fifo abierto para la escritura y se mantenga funcionando indefinidamente. Esto evitará que los lectores vean una condición de fin de archivo.

Cuestiones relacionadas