Para aquellos que tienen un programa que escribe continuamente en stdout, todo lo que necesita hacer es canalizarlo a grep con la opción de 'coincidencia única'. Una vez que grep encuentre la cadena coincidente, saldrá, lo que cierra stdout en el proceso que se está canalizando a grep. Este evento debería hacer que el programa salga con gracia siempre que el proceso vuelva a escribir .
Lo que sucederá es que el proceso recibirá un SIGPIPE cuando intente escribir en stdout cerrado después de que grep haya salido. Aquí hay un ejemplo con ping, que de otro modo se ejecutaría indefinidamente:
$ ping superuser.com | grep -m 1 "icmp_seq"
Este comando coincidirá con el primer 'pong' exitoso y luego saldrá la próxima vez que ping
intente escribir en stdout.
Sin embargo,
No siempre se garantiza que el proceso volverá a escribir en stdout y, por lo tanto, podría no provocar que se genere un SIGPIPE (por ejemplo, esto puede suceder cuando se sigue un archivo de registro). La mejor solución que he logrado encontrar para este escenario implica escribir en un archivo; comente si cree que puede mejorar:
$ { tail -f log_file & echo $! > pid; } | { grep -m1 "find_me" && kill -9 $(cat pid) && rm pid; }
Desglosando esto:
tail -f log_file & echo $! > pid
- sigue un archivo, adjunta el proceso al fondo y guarda el PID ( $!
) en un archivo. Intenté exportar el PID a una variable, pero parece que hay una condición de carrera entre aquí y cuando el PID se usa nuevamente.
{ ... ;}
- Agrupe estos comandos para que podamos canalizar la salida a grep manteniendo el contexto actual (ayuda al guardar y reutilizar variables, pero no fue capaz de hacer que esa parte funcione)
|
- canaliza el stdout del lado izquierdo al stdin del lado derecho
grep -m1 "find_me"
- encuentra la cadena objetivo
&& kill -9 $(cat pid)
- force kill (SIGKILL) el tail
proceso después de grep
salir una vez que encuentra la cadena coincidente
&& rm pid
- eliminar el archivo que creamos
tail -f
una salida del programa tan bien como un archivo ... ¿Me equivoco?