Estoy buscando una manera de mirar programáticamente la salida de un comando hasta que se observe una cadena en particular y luego salga. Esto es muy similar a esta pregunta, pero en lugar de seguir un archivo, quiero 'seguir' un comando.
Algo como:
reloj -n1 my_cmd | grep -m 1 "Cadena que estoy buscando"
(Pero esto no funciona para mí).
ACTUALIZACIÓN: necesito aclarar que 'my_cmd' no genera texto de forma continua, sino que debe llamarse repetidamente hasta que se encuentre la cadena (por eso pensé en el comando 'watch'). A este respecto, 'my_cmd' es como muchos otros comandos de Unix como: ps, ls, lsof, last, etc.
tail -f
una salida del programa tan bien como un archivo ... ¿Me equivoco?Respuestas:
Usa un bucle:
En lugar de
:
, puede usarsleep 1
(o 0.2) para facilitar la CPU.El ciclo 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 puede usar
grep -q
que también se cierra después de encontrar la primera coincidencia, pero sin imprimir la línea coincidente.fuente
grep -q
cuál es otra opción. grep se cierra después de encontrar la cadena.!
niega el código de salida de la tubería de comandogrep -m 1
sale cuando se encuentra la cadenawatch -e
devuelve si ha ocurrido algún errorPero esto se puede mejorar para mostrar realmente esa línea coincidente, que se ha descartado hasta ahora.
fuente
watch
comando (CentOS) no tiene la-e
bandera (que realmente no debería importar). Sin embargo, lo más importante es que cuando se encuentra la cadena, el reloj continúa ejecutándose y no sale. Parece que cuandogrep -m
sale, solo sale matamy_cmd
, pero nowatch
.tee
para eso, pero esto introduce una nueva línea engañosa, no sé cómo eludir en este momento:watch -n1 -e "! date | tee /dev/tty | grep --color -m 1 \"17\""
watch
obedientemente deja de mirar cuando se encuentra la cadena, pero en realidad no sale hasta que presiona una tecla. Tan cerca.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:
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:
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 derechogrep -m1 "find_me"
- encuentra la cadena objetivo&& kill -9 $(cat pid)
- force kill (SIGKILL) eltail
proceso después degrep
salir una vez que encuentra la cadena coincidente&& rm pid
- eliminar el archivo que creamosfuente
Si
tail
no admite la+1f
sintaxis, intentetail -f -n +1
. (El-n +1
le dice que comience desde el principio;tail -f
por defecto comienza con las últimas 10 líneas de salida).fuente
Agregue el resultado de sus llamadas de programa a un archivo. Entonces
tail -f
ese archivo. De esa manera debería funcionar ... espero.Cuando reinicie la llamada a ese programa, tendrá que borrar el archivo o agregarle algunas tonterías para que no vuelva a coincidir de inmediato con lo que estaba buscando.
fuente