reindirizzare e registrare l'output dello script


8

Sto cercando di riordinare i seguenti frammenti, gli obiettivi di progettazione sono di registrare tutto l'output di uno script e non dovrebbe essere un wrapper. Meno linee sono migliori.

Non mi interessa l'input dell'utente (in questa fase), gli script target vengono eseguiti in modo non interattivo.

Lo snippet deve

  • output stdout per il log ed eco sempre alla console
  • emette stderr per il log ed echo per console se il debug è abilitato
  • i messaggi stderr devono essere preceduti da timestamp e altra utilità

Al momento ho il seguente che prova solo nelle versioni recenti di bash (4.2+?) Come in Ubuntu preciso, ma si comporta male su CentOS6.

DEBUG_LOG="${0##*/}.log"

# copy stdout to log always and echo to console
exec >  >(tee -a ${DEBUG_LOG})           

# copy stderr to log only, unless debugging is enabled
[ $DEBUG_TEST = "true" ] \
  && exec 2> >(tee -a ${DEBUG_LOG} >&2) \
  || exec 2>> ${DEBUG_LOG}

Poi questo...

# Expand escaped characters, wrap at 70 chars on spaces, 
# and indent wrapped lines
msg_log() { 
  echo -e "$(date +%T) ${0##*/}: $1" \
    | fold -w70 -s | sed '2~1s/^/  /' >&2; 
}
msg_con() { 
  if [ "${DEBUG_TEST}" = "true" ]; then 
    msg_log "$1"
  else
    echo -e "$1" | fold -w70 -s | sed '2~1s/^/  /'; 
  fi
}

Invece di echoposso chiamare una di quelle procedure di msg, ad es msg_con "hello world".
Anche l'output dello script andrà quindi su stderr impostando come variabile di ambiente al momento della chiamata, ad es  DEBUG_TEST=true myscript.

Ho letto che exec potrebbe non funzionare in alcune shell come busybox. C'è una combinazione mkfifo e fork su https://stackoverflow.com/a/5200754 che fa qualcosa di simile ma preferirei non usare fork se non assolutamente necessario.

Preferisci esempi bash per favore, ma qualcosa che funziona sotto sh o è più portatile sarebbe bello. Qualche idea?

Risposte:


1
function startLogging {
    exec > >(gawk -v pid=$$ '{ print strftime("%F-%T"),pid,$0; fflush(); }' | tee -a $logfile)
    [ ! -z "$DEBUG" ] && exec 2>&1 || exec 2> >(gawk -v pid=$$ '{ print strftime("%F-%T"),pid,$0; fflush(); }' >>$logfile)
    echo "=== Log started for $$ at $(date +%F-%T) ==="
}

Devi avere $ logfile impostato su qualcosa


Questo è abbastanza bello, nel modo in cui lo sto leggendo usi gawk per aggiungere le intestazioni dei messaggi. Ciò avrà l'ulteriore effetto collaterale di aggiungere anche quelli agli output dei comandi.
Glenn,

Il motivo per usare gawk per aggiungere un timestamp (e ID processo) a ciascuna riga di registro è perché verrà eseguito ogni volta che viene scritto l'output e quindi aggiorna il timestamp. Inoltre è importante usare gawk e non awk perché penso che la funzione strftime sia un'estensione GNU.
Angelo,

0

exec > filenamedovrebbe funzionare in sh, e in realtà funziona in busybox v1.15.3 (Nov 2011). Ma la sostituzione del processo >(command)è insostituibile poiché è estensione bash. Evita di usarlo negli script. Perché >>non è abbastanza per te?

exec 1>>${DEBUG_LOG}
exec 2>>${DEBUG_LOG}

Un'altra soluzione è specificare il reindirizzamento al di fuori dei tuoi script. Quando il tuo script viene invocato in background (da cron, o script di sistema, ecc.), Dovrebbero essere chiamati in questo modo

./my_script 1>>${DEBUG_LOG} 2>>${DEBUG_LOG}

Quando invochi manualmente lo script e vuoi vedere l'output, chiamalo senza reindirizzamenti.


1
Chi pone la domanda vuole che l'output dello script vada sia alla console che al file di registro.

0

Questi due esempi faranno quali sono i tuoi obiettivi dichiarati

echo -n $(date) >> $DEBUG_LOG
command 2>&1 | tee -a $DEBUG_LOG

o

echo -n $(date) >> $DEBUG_LOG
command >> $DEBUG_LOG 2>&1

0

È possibile utilizzare il teecomando o scriptentrambi i comandi sono davvero utili.


lo script sembra interessante, ma in realtà non fa ciò di cui ho bisogno, il comportamento deve essere modificabile durante il runtime.
Glenn,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.