Si no hay nada en una tubería con nombre y hago:
cat my_named_pipe
esperará hasta que lleguen los datos. ¿Existe algún indicador que pueda utilizar para salir inmediatamente si no hay datos para leer? ¿O quizás algún comando distinto de cat que pueda usar?
También probé:
read val < "$my_named_pipe";
pero esto también espera la siguiente porción de datos; no quiero esperar si el quince está vacío.
Respuesta1
Para evitar cat
que se cuelgue en ausencia de cualquier escritor (en cuyo caso es la apertura del quince, no la lectura de él, la que se cuelga), puede hacer:
cat 0<> "$my_named_pipe" <"$my_named_pipe"
La primera redirección se abre en modo lectura+escritura, que en la mayoría de los sistemas no bloquea y crea una instancia de la canalización incluso si ya no hay ningún escritor ni lector. Entonces, la segunda apertura (esta vez de solo lectura) no se bloquearía porque ahora hay al menos un escritor (él mismo).
Solo es 0
necesario en versiones recientes de ksh93 donde el fd predeterminado <>
cambió de 0 a 1.
Además, en ksh93
, eso no funcionaría cuando cat
el shell está incorporado, como cuando ksh93
se llama cuando /opt/ast/bin
está antes o después /bin
de $PATH
una llamada a builtin cat
como en <"$my_named_pipe"
, (supongo) ksh93 guarda el objetivo anterior de stdin en un descriptor de archivo separado que mantenga la tubería abierta. Puedes solucionarlo escribiéndolo en su lugar:
cat 3<> "$my_named_pipe" <"$my_named_pipe" 3<&-
(que también se podría argumentar que transmite la intención más claramente)
Tenga en cuenta que eso <>
en la tubería también desbloquearía otros lectores en el quince.
Si hubiera algunos escritores, cat
aún tendrían que leer todos sus resultados y esperar hasta que hayan cerrado el extremo de la tubería. Podrías abrir la tubería en modo sin bloqueo, como con GNU dd
:
dd bs=64k if="$my_named_pipe" iflag=nonblock status=noxfer
Que solo leerá de la tubería siempre que haya algunos datos en ella y saldrá con un
dd: error reading 'fifo': Resource temporarily unavailable
error cuando no hay más, y no desbloquea otros lectores, pero eso significa que podría perder algunos de los resultados de los escritores si son más lentos para escribir en la tubería que usted ( dd
) para leerlos.
Otro enfoque podría ser el tiempo de espera cuando no ha habido entrada por un tiempo, por ejemplo usando socat
la opción ' -T
:
socat -u -T1 - - 0<> "$my_named_pipe" <"$my_named_pipe"
Que saldría si no hubiera salido nada de la tubería en un segundo.
Respuesta2
Algo bastante fácil sería terminar cat
inmediatamente después de leer el quince, independientemente de si hay datos o no. Podrías hacer esto con timeout
, de la siguiente manera:
timeout 2 cat my_named_pipe
Arriba, timeout
espera dos segundos antes de obligar al gato a terminar. Si hay algo almacenado en el buffer en la canalización con nombre cuando ejecuta cat
, se imprimirá en la salida estándar.
Quizás no sea la solución más limpia, pero funciona.
Espero eso ayude.