GNU/Linux >> Tutoriales Linux >  >> Linux

observe la salida de un comando hasta que se observe una cadena en particular y luego salga

Usa un bucle:

until my_cmd | grep -m 1 "String Im Looking For"; do : ; done

En lugar de : , puedes usar sleep 1 (o 0.2) para facilitar la CPU.

El bucle se ejecuta hasta que grep encuentra la cadena en la salida del comando. -m 1 significa "una coincidencia es suficiente", es decir, grep deja de buscar después de encontrar la primera coincidencia.

También puedes usar grep -q que también se cierra después de encontrar la primera coincidencia, pero sin imprimir la línea correspondiente.


watch -e "! my_cmd | grep -m 1 \"String Im Looking For\""
  • ! niega el código de salida de la canalización de comandos
  • grep -m 1 sale cuando se encuentra una cadena
  • watch -e devuelve si se ha producido algún error

Pero esto se puede mejorar para mostrar realmente esa línea coincidente, que hasta ahora se descarta.


Para aquellos que tienen un programa que escribe continuamente en stdout, todo lo que necesitan hacer es canalizarlo a grep con la opción 'coincidencia única'. Una vez que grep encuentre la cadena coincidente, saldrá, lo que cierra la salida estándar en el proceso que se está canalizando a grep. Este evento debería naturalmente, hace que el programa salga correctamente siempre y cuando el proceso vuelva a escribir .

Lo que sucederá es que el proceso recibirá un SIGPIPE cuando intente escribir en la salida estándar cerrada 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 ping intenta escribir en stdout.

Sin embargo,

No siempre se garantiza que el proceso vuelva a escribir en la salida estándar y, por lo tanto, es posible que no genere un SIGPIPE (por ejemplo, esto puede suceder cuando se sigue un archivo de registro). La mejor solución que he encontrado para este escenario consiste en escribir en un archivo; por favor comente si cree que puede mejorar:

$ { tail -f log_file & echo $! > pid; } | { grep -m1 "find_me" && kill -9 $(cat pid) && rm pid; }

Desglosando esto:

  1. tail -f log_file & echo $! > pid - sigue un archivo, adjunta el proceso al fondo y guarda el PID ($! ) a un archivo. Intenté exportar el PID a una variable en su lugar, pero parece que hay una condición de carrera entre aquí y cuando se vuelve a usar el PID.
  2. { ... ;} - Agrupe estos comandos para que podamos canalizar la salida a grep mientras mantenemos el contexto actual (ayuda al guardar y reutilizar variables, pero no pudo hacer que esa parte funcionara)
  3. | - canalizar la salida estándar del lado izquierdo a la entrada estándar del lado derecho
  4. grep -m1 "find_me" - encuentra la cadena de destino
  5. && kill -9 $(cat pid) - fuerza matar (SIGKILL) el tail proceso después grep sale una vez que encuentra la cadena coincidente
  6. && rm pid - eliminar el archivo que creamos

Linux
  1. Cómo capturar sesiones de terminal y salida con el comando de script de Linux

  2. Salida a Stdout y al mismo tiempo Grep en un archivo?

  3. ¿Usar el comando Grep y localizar?

  4. CentOS/RHEL:cómo obtener la fecha y la hora del comando ejecutado en la salida del comando del historial

  5. Convertir una salida a cadena

Comando de salida de Bash y códigos de salida

Prettyping:haga que la salida del comando Ping sea más bonita y fácil de leer

Uso del comando grep en Linux

¿Cómo capturar la salida de un comando superior en un archivo en Linux?

Almacene la salida del comando de fecha y reloj en un archivo

¿Dejar de ver la salida de un programa en particular después de usar el comando watch?