GNU/Linux >> Tutoriales Linux >  >> Linux

¿Hacer Tail -f Exit en una tubería rota?

Quiero ver un archivo hasta que aparezca un poco de texto

Encontré esta respuesta:`tail -f` hasta que se vea el texto

pero cuando lo probé en ubuntu, no sale:

$ echo one > test.txt
$ echo two >> test.txt
$ echo three >> test.txt
$ echo four >> test.txt
$ cat test.txt | sed '/w/ q'
one
two
$

funciona como se esperaba. sin embargo, cuando trato de rastrear el archivo

$ tail -f test.txt | sed '/w/ q'
one
two

nunca sale. cola no se detiene a pesar de que la tubería está rota.

¿Alguien sabe cómo hacer tail? salir cuando sed salidas?

Respuesta aceptada:

Es lo mismo que en:

  • ¿Cómo salir temprano en el cierre de la tubería?
  • ¿Grep tarda en salir después de encontrar una coincidencia?
  • limitar la salida de búsqueda Y evitar la señal 13

en:

cmd1 | cmd2

Su shell espera hasta cmd1 termina incluso después de cmd2 ya ha terminado. Ese no es el caso de todas las conchas. Algunos como el shell Bourne o Korn, por ejemplo, no lo hacen.

Cuando cmd2 muere, la tubería en cmd1 's stdout se vuelve roto , pero eso no termina cmd1 al instante.

cmd1 terminará la próxima vez que intente escribir en esa tubería. Luego recibirá un SIGPIPE cuya acción predeterminada es finalizar el proceso.

Con cmd1 ==tail -f file y cmd2 ==sed /w/q , tail -f leerá las últimas 10 líneas del archivo y las escribirá en la salida estándar (la canalización), generalmente en un solo fragmento, a menos que las líneas sean realmente grandes y se queden allí esperando que se agregue más texto al file .

sed , que se ejecuta simultáneamente, esperará la entrada en su entrada estándar, la leerá, la procesará línea por línea y se cerrará si hay una línea que contenga w .

Tan pronto (o posiblemente con una demora de una línea con algo de sed) implementación) cuando encuentra esa línea, sale, pero en ese momento, tail ya ha escrito en la tubería todo lo que tenía que ESCRIBIR, por lo que no recibirá un SIGPIPE a menos que se agregue algún texto adicional más adelante al archivo (momento en el cual hará el fatal write() ).

Si quisiera cmd1 para terminar tan pronto como cmd2 termina, necesitarías algo para matarlo una vez cmd2 termina Me gusta con:

sh -c 'echo "$$"; exec tail -f test.txt' | {
  IFS= read pid
  sed /w/q
  kill -s PIPE "$pid"
}

O con bash :

{ sed /w/q; kill -s PIPE "$!"; } < <(exec tail -f text.txt)
  

Editar 2020

Como señaló @user414777, desde la versión 8.28, la implementación GNU de tail , en los modos de seguimiento, ahora no solo busca nuevos datos en los archivos que monitorea, sino que también verifica si su salida estándar se convierte en una tubería rota y sale de inmediato (o dentro de un segundo si inotify no se usa), lo que hace innecesarias las soluciones anteriores.

Relacionado:¿Cómo usar el código de estado de salida?

Sin embargo, tenga en cuenta que solo GNU tail hace este tipo de procesamiento, no cualquier otra implementación de tail (AFAIK), y ninguna otra utilidad (incluso las implementaciones de GNU).

Entonces, mientras:

tail -f file | head -n1

Saldrá después de una línea,

tail -f file | tr '[:lower:]' '[:upper:]' | head -n1

por ejemplo, no necesariamente como tr no supervisará si su salida estándar se convierte en una tubería rota, por lo que solo morirá si escribe algo allí después de que la tubería se haya roto como de costumbre (y es solo en ese punto que GNU tail -f saldrá).


Linux
  1. ¿Cómo hacer que el archivo sea disperso?

  2. Canalice la cadena a la fecha GNU para la conversión:¿cómo hacer que se lea desde la entrada estándar?

  3. ¿Cómo obtener el estado de salida de un comando de shell utilizado en GNU Makefile?

  4. La tubería rota EC2 ssh finaliza el proceso en ejecución

  5. Makefile para no hacer nada

Comando de cola de Linux

¿Cómo hacer una tubería bidireccional entre dos programas?

Tubería B a D? – A &&B || C | ¿D?

Grep y cola -f?

Reparación de error de tubería rota con conexión SSH

¿Puedo hacer que Qemu salga con falla en kernel panic?