Gibt es ein Tool, um die Ausgabe auf Anfrage dynamisch in eine neue Datei umzuleiten?

8

Ich leite derzeit die Ausgabe eines Überwachungstools in eine Datei um. Ich möchte diese Ausgabe jedoch auf meine Anfrage (mithilfe einer Tastenkombination) in eine neue Datei umleiten, ohne das Tool anzuhalten.

Etwas wie

monitor_program | handle_stdout

Wo handle_stdoutkann ich eine neue Datei definieren, in der das Protokoll an einem bestimmten Punkt abgelegt werden soll?

Ich weiß, dass ich es leicht schreiben könnte, aber ich frage mich, ob es ein Tool gibt, das dies bereits zulässt.

Treviño
quelle
Sie könnten wahrscheinlich logrotatemanuell mit einer benutzerdefinierten Konfigurationsdatei ausgeführt werden, abhängig vom Verhalten Ihres monitor_program, aber das ist etwas hackisch.
Ulrich Schwarz
Es scheint, dass Ihre Bearbeitung tatsächlich eine Antwort auf die Frage ist. In diesem Fall posten Sie es bitte als Antwort (Selbstantworten werden empfohlen!) Und entfernen Sie die Antwort aus Ihrer Frage.
Katze

Antworten:

9

Ich werde eine Named Pipe vorschlagen.

  1. Erstellen Sie eine Pipe mkfifo p(nennen Sie es wie Sie wollen, wenn nicht 'p')

  2. Erstellen Sie ein "Reader" -Skript, das aus der Pipe liest und schreibt, wo immer Sie möchten

  3. Weisen Sie das Überwachungsprogramm an, seine Protokolle in die Named Pipe zu schreiben

Hier ist ein Beispielleser-Skript, das aus einer Named Pipe 'p' liest und die Daten in eine indizierte 'mylog'-Datei schreibt:

#!/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
quelle
2
Sie können auch ein Signal (z. B. USR1) im Readerskript als Signal zum Wechseln von Protokollen abfangen.
Jeff Schaller
Dies ist etwas, das ich brauchen würde ... Das Readerskript sollte jedoch in der Lage sein, die Ausgabe basierend auf meiner Kebinding zu ändern. Und fragen Sie mich möglicherweise nach einem neuen Dateinamen (obwohl dies optional ist, auch wenn sequentielle Protokollnamen in Ordnung wären)
Treviño
Ich habe das Beispielskript bearbeitet, um ein Beispiel für das Umschalten von Protokollen mit kill -USR1 zu zeigen. Geben Sie eine neue Nummer in die 'newindex'-Datei ein, damit sie abgerufen werden kann.
Jeff Schaller
1
Nur eine weitere Idee: Wenn Sie ein Fenster für das laufende "Reader" -Skript offen halten, können Sie "INT" anstelle von USR1 abfangen und in diesem Fenster einfach Strg-C drücken, um einen neuen Protokolldateinamen zu benachrichtigen.
Jeff Schaller
1
Warum readund printfstatt nur cat <p >> mylog."$INDEX"?
Wildcard
7

Aufbauend auf Ihrer SIGINT-Idee können Sie hier mit SIGQUIT ( Ctrl+\) immer noch Ctrl+Cdas Ganze stoppen:

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

catDies setzt voraus, dass es sich nicht um ein integriertes Element in Ihrer Shell handelt (es wird also durch Drücken von unterbrochen Ctrl+\).

Beachten Sie, dass wie bei Ihrem Ansatz die Möglichkeit besteht, dass das SIGQUIT zum falschen Zeitpunkt (beim Aufruf des Schreibsystems) zugestellt wird und einige Daten verloren gehen.

Stéphane Chazelas
quelle
1

Sie könnten wahrscheinlich lessvon dort aus verwenden und speichern, indem Sie sdann den Dateinamen eingeben, in dem Sie speichern möchten Enter. Von Wie schreibe ich alle Zeilen von weniger in eine Datei? .

BenjaminH
quelle
Leider ist es nicht möglich, mehr Protokolldateien zu verwenden. Sobald Sie eine festgelegt haben, können Sie keine neue neu definieren. Sie können das Protokoll auch nicht löschen, wenn Sie fertig sind. Also ... Guter Ausgangspunkt (danke), aber noch nicht genug.
Treviño
0

Ohne mehr über Ihre "Anfrage" zu wissen, ist es nicht wirklich möglich zu antworten. Wenn es auf der Dateigröße oder dem Intervall basieren würde, würden Rotatelogs (die mit Apache httpd gebündelt sein sollten) funktionieren.

symcbean
quelle
Entschuldigung, das habe ich nicht explizit gesagt. Ich gehe von einer Tastenkombination aus, mit der der Protokollname geändert werden kann.
Treviño
0

Dank der Antwort von Jeff Schaller kam ich zu so etwas, das im Grunde das tut, was ich brauche. Nennen wir es 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

Dann geht es nur noch darum, eine Named Pipe mit mkfifo pund mit zwei Terminals zu erstellen , auf denen monitor_program > pund ausgeführt reader.shwerden. Ich kann dann den Leser anhalten, um mit Ctrl+ ein neues Protokoll zu erstellen C, und einen neuen Namen eingeben. Ctrl+ Z, wie immer dann, um anzuhalten und es zu töten.

Treviño
quelle