GNU/Linux >> Linux Esercitazione >  >> Linux

Come terminare il comando tee di Linux senza uccidere l'applicazione da cui sta ricevendo

Quando tee termina, il comando che lo alimenta continuerà a essere eseguito, fino a quando non tenterà di scrivere altro output. Quindi otterrà un SIGPIPE (13 sulla maggior parte dei sistemi) per provare a scrivere su una pipe senza lettori.

Se modifichi il tuo script per intercettare SIGPIPE e intraprendi un'azione appropriata (come, interrompi la scrittura dell'output), dovresti essere in grado di farlo continuare dopo che tee è terminato.

Meglio ancora, piuttosto che uccidere tee per niente, usa logrotate con il copytruncate opzione per semplicità.

Per citare logrotate(8) :

copytruncate

Tronca il file di registro originale in posizione dopo averne creato una copia, invece di spostare il vecchio file di registro e, facoltativamente, crearne uno nuovo. Può essere utilizzato quando non si può dire a qualche programma di chiudere il suo file di registro e quindi potrebbe continuare a scrivere (aggiungere) al file di registro precedente per sempre. Si noti che esiste un intervallo di tempo molto breve tra la copia del file e il suo troncamento, quindi alcuni dati di registrazione potrebbero andare persi. Quando viene utilizzata questa opzione, l'opzione create non avrà alcun effetto, poiché il vecchio file di registro rimane al suo posto.


Spiegazione del "perché"

In breve:se le scritture falliscono non causare l'uscita di un programma (per impostazione predefinita), avremmo un pasticcio. Considera find . | head -n 10 -- non vuoi find per continuare a eseguire la scansione del resto del disco rigido, dopo head ha già preso le 10 righe di cui aveva bisogno e ha proceduto.

Fallo meglio:ruota all'interno del tuo logger

Considera quanto segue, che non usa tee affatto, come esempio dimostrativo:

#!/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

Se eseguito come:

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

...questo inizierà aggiungendo a /tmp/nginx/debug_log , rinominando il file in /tmp/nginx/debug_log.old quando sono presenti oltre 100KB di contenuti. Poiché è il logger stesso a eseguire la rotazione, non ci sono pipe rotte, errori e finestre di perdita di dati quando avviene la rotazione:ogni riga verrà scritta in un file o in un altro.

Naturalmente, l'implementazione di questo in bash nativo è inefficiente, ma quanto sopra è un esempio illustrativo. Sono disponibili numerosi programmi che implementeranno la logica di cui sopra per te. Considera:

  • svlogd , il service logger della suite Runit.
  • s6-log , un'alternativa mantenuta attivamente dalla suite skanet.
  • multilog da DJB Daemontools, il nonno di questa famiglia di strumenti per la supervisione e il monitoraggio dei processi.

Linux
  1. Come salvare l'output dei comandi in un file in Linux

  2. Come eliminare file e directory in Linux dalla riga di comando

  3. Come dividere e combinare file dalla riga di comando in Linux

  4. Comando SCP Linux – Come trasferire file SSH da remoto a locale

  5. Come creare un file in Linux dalla finestra del terminale?

Come usare il comando Tronca in Linux

Come mescolare le linee in un file in Linux

Come rimuovere un comando dalla cronologia in Linux

Come rimuovere (^M) caratteri da un file in Linux

Come usare il comando lsof in Linux

Come utilizzare il comando shred Linux