¿Existe una herramienta para redirigir dinámicamente la salida a un nuevo archivo a pedido?

8

Actualmente estoy redirigiendo la salida de una herramienta de monitoreo a un archivo, sin embargo, lo que me gustaría hacer es redirigir esta salida a un nuevo archivo en mi solicitud (usando una combinación de teclas), sin detener dicha herramienta.

Algo como

monitor_program | handle_stdout

Where handle_stdoutme permite definir un nuevo archivo donde colocar el registro en cierto punto.

Sé que podría escribirlo fácilmente, pero me pregunto si hay alguna herramienta que ya lo permita.

Treviño
fuente
Probablemente podría ejecutar logrotatemanualmente un archivo de configuración personalizado, dependiendo del comportamiento de su monitor_programa, pero eso es algo hack.
Ulrich Schwarz
Parece que tu edición es en realidad una respuesta a la pregunta. En ese caso, publíquelo como respuesta (se alientan las respuestas personales) y elimine la respuesta de su pregunta.
gato

Respuestas:

9

Sugeriré una pipa con nombre.

  1. Crea una tubería mkfifo p(llámalo como quieras, si no es 'p')

  2. Cree un script de "lector" que lea desde la tubería y escriba donde quiera

  3. Dígale al programa de monitoreo que escriba sus registros en la tubería nombrada

Aquí hay una secuencia de comandos de lector de muestra que lee de una tubería con nombre 'p' y escribe los datos en un archivo indexado 'mylog':

#!/bin/sh

INDEX=0

switchlog() {
  read INDEX < newindex
  echo now writing to "mylog.$INDEX"
}

trap switchlog USR1

while :
do
  cat p >> mylog."$INDEX"
done
Jeff Schaller
fuente
2
También puede atrapar una señal (USR1, por ejemplo) en el script del lector como la señal para cambiar los registros.
Jeff Schaller
Esto comienza a ser algo que necesitaría ... Sin embargo, la secuencia de comandos del lector debería poder cambiar la salida en función de mi combinación de claves. Y potencialmente pedirme un nuevo nombre de archivo para usar (aunque esto es opcional, incluso tener nombres de registro secuenciales estaría bien)
Treviño
Edité el script de muestra para mostrar un ejemplo de cambio de registro con kill -USR1. haga eco de un nuevo número en el archivo 'newindex' para que lo recoja.
Jeff Schaller
1
Otra idea más: si mantiene una ventana abierta para el script "lector" en ejecución, podría atrapar 'INT' en lugar de USR1 y simplemente presionar Control-C en esa ventana para notificarle un nuevo nombre de archivo de registro.
Jeff Schaller
1
¿Por qué ready en printflugar de solo cat <p >> mylog."$INDEX"?
Wildcard
7

A partir de su idea SIGINT, aquí puede usar SIGQUIT ( Ctrl+\) que aún puede usar Ctrl+Cpara detener todo:

(trap '' QUIT; monitor_command) | (
   trap : QUIT
   ulimit -c 0 # prevent core dump so SIGQUIT behaves like SIGINT
               # for cat
   n=0; while n=$((n+1)); file=output.$n.log; do
     printf 'Outputting to "%s"\n' "$file"
     cat > "$file"
   done)

Eso supone catque no está integrado en su caparazón (por lo que se interrumpe al presionar Ctrl+\).

Tenga en cuenta que, al igual que en su enfoque, existe la posibilidad de que el SIGQUIT se entregue en el momento equivocado (en la llamada al sistema de escritura) y que se pierdan algunos datos.

Stéphane Chazelas
fuente
1

Probablemente podría usar lessy guardar desde allí escribiendo sluego el nombre del archivo en el que desea guardar Enter. De ¿Cómo escribo todas las líneas de menos a un archivo? .

BenjaminH
fuente
Desafortunadamente, no es posible usar más archivos de registro, una vez que ha configurado uno, no puede redefinir uno nuevo. Además, no puede borrar el registro una vez hecho. Entonces ... Buen punto de partida (gracias), pero aún no lo suficiente.
Treviño
0

Sin saber más acerca de su "solicitud" no es realmente posible responder. Si se basara en el tamaño o intervalo del archivo, los rotatelogs (que deberían venir incluidos con Apache httpd) funcionarían.

symcbean
fuente
Lo siento, no dije eso explícitamente, estoy asumiendo una combinación de teclas que permitiría cambiar el nombre del registro.
Treviño
0

Gracias a la respuesta de Jeff Schaller , terminé con algo como esto, que básicamente hace lo que necesito, llamémoslo reader.sh:

#!/bin/sh

INDEX=0
LOGNAME="$INDEX.log"

switchlog() {
  local custom_name
  read -p "Add log name: " custom_name
  INDEX=$((INDEX+1))
  LOGNAME="$(printf "%03d" $INDEX).$custom_name.log"
  echo now writing to $LOGNAME
}

trap switchlog INT
switchlog

while :
do
  read foo < p
  printf "%s\n" "$foo" >> "$LOGNAME"
done

Luego se trata de crear una tubería con nombre mkfifo py usar dos terminales donde monitor_program > py se reader.shestén ejecutando. Luego puedo detener al lector para establecer un nuevo registro usando Ctrl+ Ce ingresar un nuevo nombre. Ctrl+ Z, como siempre, entonces para detenerlo y matarlo.

Treviño
fuente