GNU/Linux >> LINUX-Kenntnisse >  >> Linux

So beenden Sie den Linux-Tee-Befehl, ohne die Anwendung zu beenden, von der er empfangen wird

Wenn tee beendet wird, wird der Befehl, der es speist, weiter ausgeführt, bis es versucht, weitere Ausgaben zu schreiben. Dann erhält es eine SIGPIPE (13 auf den meisten Systemen) für den Versuch, in eine Pipe ohne Leser zu schreiben.

Wenn Sie Ihr Skript so ändern, dass es SIGPIPE abfängt und eine geeignete Aktion ausführt (z. B. das Schreiben von Ausgaben beenden), sollten Sie in der Lage sein, es fortzusetzen, nachdem tee beendet wurde.

Besser noch, anstatt tee zu töten überhaupt Verwenden Sie logrotate mit dem copytruncate Option der Einfachheit halber.

Um logrotate(8) zu zitieren :

copytruncate

Kürzen Sie die ursprüngliche Protokolldatei an Ort und Stelle, nachdem Sie eine Kopie erstellt haben, anstatt die alte Protokolldatei zu verschieben und optional eine neue zu erstellen. Es kann verwendet werden, wenn einem Programm nicht gesagt werden kann, dass es seine Protokolldatei schließen soll, und daher möglicherweise für immer an die vorherige Protokolldatei geschrieben (angehängt) wird. Beachten Sie, dass zwischen dem Kopieren der Datei und dem Abschneiden nur ein sehr kleiner Zeitabschnitt liegt, sodass möglicherweise einige Protokolldaten verloren gehen. Wenn diese Option verwendet wird, hat die Erstellungsoption keine Auswirkung, da die alte Protokolldatei bestehen bleibt.


Das „Warum“ erklären

Kurz gesagt:Wenn Schreibvorgänge nicht fehlschlugen ein Programm zum Beenden bringen (standardmäßig), hätten wir ein Durcheinander. Betrachten Sie find . | head -n 10 -- Sie wollen find nicht um weiterzumachen und den Rest Ihrer Festplatte zu scannen, nach head hat bereits die 10 benötigten Zeilen genommen und ist weitergefahren.

Besser machen:Rotieren Sie in Ihrem Logger

Betrachten Sie das Folgende, das tee nicht verwendet überhaupt, als anschauliches Beispiel:

#!/usr/bin/env bash

file=${1:-debug.log}                     # filename as 1st argument
max_size=${2:-100000}                    # max size as 2nd argument
size=$(stat --format=%s -- "$file") || exit  # Use GNU stat to retrieve size
exec >>"$file"                           # Open file for append

while IFS= read -r line; do              # read a line from stdin
  size=$(( size + ${#line} + 1 ))        # add line's length + 1 to our counter
  if (( size > max_size )); then         # and if it exceeds our maximum...
    mv -- "$file" "$file.old"            # ...rename the file away...
    exec >"$file"                        # ...and reopen a new file as stdout
    size=0                               # ...resetting our size counter
  fi
  printf '%s\n' "$line"                  # regardless, append to our current stdout
done

Wenn ausgeführt als:

/mnt/apps/start.sh 2>&1 | above-script /tmp/nginx/debug_log

... dies beginnt mit dem Anhängen an /tmp/nginx/debug_log , indem Sie die Datei in /tmp/nginx/debug_log.old umbenennen wenn über 100 KB Inhalt vorhanden sind. Da der Logger selbst die Rotation durchführt, gibt es keine gebrochene Leitung, keinen Fehler und kein Datenverlustfenster, wenn die Rotation stattfindet – jede Zeile wird in die eine oder andere Datei geschrieben.

Natürlich ist die Implementierung in nativer Bash ineffizient, aber das obige ist ein anschauliches Beispiel. Es stehen zahlreiche Programme zur Verfügung, die die obige Logik für Sie implementieren. Bedenken Sie:

  • svlogd , der Service-Logger aus der Runit-Suite.
  • s6-log , eine aktiv gepflegte Alternative aus der skanet-Suite.
  • multilog von DJB Daemontools, dem Urvater dieser Familie von Prozessüberwachungs- und Überwachungstools.

Linux
  1. So speichern Sie die Befehlsausgabe in einer Datei unter Linux

  2. So löschen Sie Dateien und Verzeichnisse in Linux über die Befehlszeile

  3. So teilen und kombinieren Sie Dateien von der Befehlszeile in Linux

  4. SCP-Linux-Befehl – ​​So übertragen Sie SSH-Dateien von Remote auf Lokal

  5. Wie erstelle ich eine Datei in Linux aus dem Terminalfenster?

So verwenden Sie den Truncate-Befehl unter Linux

So mischen Sie Zeilen in einer Datei unter Linux

So entfernen Sie einen Befehl aus dem Verlauf in Linux

So entfernen Sie (^M) Zeichen aus einer Datei in Linux

So verwenden Sie den Befehl lsof unter Linux

So verwenden Sie den Linux-Befehl shred