Existe-t-il un outil pour rediriger dynamiquement la sortie vers un nouveau fichier sur demande

8

Je redirige actuellement la sortie d'un outil de surveillance vers un fichier, mais ce que j'aimerais faire, c'est rediriger cette sortie vers un nouveau fichier à ma demande (en utilisant un raccourci clavier), sans arrêter ledit outil.

Quelque chose comme

monitor_program | handle_stdout

handle_stdoutme permet de définir un nouveau fichier où mettre le journal à un certain point.

Je sais que je pourrais facilement l'écrire, mais je me demande s'il existe un outil qui le permet déjà.

Treviño
la source
Vous pouvez probablement exécuter logrotatemanuellement un fichier de configuration personnalisé, selon le comportement de votre moniteur_programme, mais c'est quelque peu hack.
Ulrich Schwarz
Il semble que votre modification soit en fait une réponse à la question. Dans ce cas, veuillez l'afficher en tant que réponse (les réponses personnelles sont encouragées!) Et supprimez la réponse de votre question.
chat

Réponses:

9

Je suggère une pipe nommée.

  1. Créez un tuyau mkfifo p(appelez-le comme vous voulez, sinon «p»)

  2. Créez un script "lecteur" qui lit à partir du tuyau et écrit où vous voulez

  3. Dites au programme de surveillance d'écrire ses journaux dans le canal nommé

Voici un exemple de script de lecture qui lit à partir d'un canal nommé «p» et écrit les données dans un fichier «mylog» indexé:

#!/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
la source
2
Vous pouvez également intercepter un signal (USR1 par exemple) dans le script de lecture comme signal de commutation des journaux.
Jeff Schaller
Cela commence à être quelque chose dont j'ai besoin ... Cependant, le script du lecteur devrait être en mesure de modifier la sortie en fonction de ma liaison. Et potentiellement me demander un nouveau nom de fichier à utiliser (bien que ce soit facultatif, même avoir des noms de journaux séquentiels serait bien)
Treviño
J'ai édité l'exemple de script pour montrer un exemple de commutation de journal avec kill -USR1. faire écho un nouveau numéro dans le fichier «newindex» pour qu'il le ramasse.
Jeff Schaller
1
juste une autre idée - si vous gardez une fenêtre ouverte pour le script "lecteur" en cours d'exécution, vous pouvez intercepter 'INT' au lieu de USR1 et simplement appuyer sur Control-C dans cette fenêtre pour lui notifier un nouveau nom de fichier journal.
Jeff Schaller
1
Pourquoi readet printfau lieu de juste cat <p >> mylog."$INDEX"?
Wildcard
7

S'appuyant sur votre idée SIGINT, ici en utilisant SIGQUIT ( Ctrl+\), vous pouvez toujours utiliser Ctrl+Cpour arrêter le tout:

(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)

Cela suppose que ce catn'est pas une fonction intégrée dans votre shell (il est donc interrompu lorsque vous appuyez sur Ctrl+\).

Notez que, comme dans votre approche, il est possible que le SIGQUIT soit livré au mauvais moment (lors de l'appel du système d'écriture), entraînant la perte de certaines données.

Stéphane Chazelas
la source
1

Vous pouvez probablement utiliser lesset enregistrer à partir de là en tapant sle nom du fichier dans lequel vous souhaitez enregistrer, puis Enter. De Comment écrire toutes les lignes de moins dans un fichier? .

BenjaminH
la source
Malheureusement, il n'est pas possible d'utiliser plus de fichiers journaux, une fois que vous en avez défini un, vous ne pouvez pas en redéfinir un nouveau. Vous ne pouvez pas non plus effacer le journal une fois terminé. Alors ... Bon point de départ (merci), mais pas encore assez.
Treviño
0

Sans en savoir plus sur votre "demande", il n'est pas vraiment possible de répondre. S'il était basé sur la taille ou l'intervalle du fichier, les rotatelogs (qui devraient être fournis avec Apache httpd) fonctionneraient.

symcbean
la source
Désolé, je n'ai pas dit cela explicitement, je suppose une liaison de touches qui permettrait de changer le nom du journal.
Treviño
0

Grâce à la réponse de Jeff Schaller , je me suis retrouvé avec quelque chose comme ça, qui fait essentiellement ce dont j'ai besoin, appelons-le 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

Ensuite, il s'agit simplement de créer un canal nommé avec mkfifo pet d'utiliser deux terminaux où monitor_program > pet reader.shsont en cours d'exécution. Je peux alors arrêter le lecteur pour définir un nouveau journal en utilisant Ctrl+ Cet entrer un nouveau nom. Ctrl+ Z, comme d'habitude alors pour arrêter et le tuer.

Treviño
la source