Cómo hacer un gato con nombre de tubería sin esperar

Cómo hacer un gato con nombre de tubería sin esperar

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 catque 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 0necesario en versiones recientes de ksh93 donde el fd predeterminado <>cambió de 0 a 1.

Además, en ksh93, eso no funcionaría cuando catel shell está incorporado, como cuando ksh93se llama cuando /opt/ast/binestá antes o después /binde $PATHuna llamada a builtin catcomo 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, cataú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 socatla 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 catinmediatamente 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, timeoutespera 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.

información relacionada