Pregunta

Ahora mismo estoy usando exec para redirigir stderr a un registro de errores con

exec 2>> ${errorLog}

El único inconveniente es que tengo que comenzar cada ejecución con una marca de tiempo ya que exec solo inserta el texto directamente en el archivo de registro. ¿Hay alguna forma de redireccionar stderr pero me permite agregarle texto, como una marca de tiempo?

¿Fue útil?

Solución

Esto es muy interesante. Le he preguntado a un tipo que sabe bastante bien el golpe, y me dijo de esta manera:

 foo() { while IFS='' read -r line; do echo "$(date) $line" >> file.txt; done; };

Primero, eso crea una función que lee una línea de entrada sin formato desde la entrada estándar, mientras que la asignación a IFS hace que no se ignoren los espacios en blanco. Después de leer una línea, la genera con los datos apropiados antepuestos. Luego tienes que decirle a bash que redirija stderr a esa función:

exec 2> >(foo)

Todo lo que escribas en stderr ahora pasará por la función foo. Tenga en cuenta que cuando lo haga en un shell interactivo, ya no verá el mensaje, porque está impreso en stderr, y la lectura en foo tiene un buffer de línea :)

Otros consejos

Usted podría simplemente usar:

exec 1> >( sed "s/^/$(date '+[%F %T]'): /" | tee -a ${LOGFILE}) 2>&1

Esto no solucionará completamente su problema con respecto a la solicitud que no se muestra (se mostrará después de un breve período de tiempo, pero no en tiempo real, ya que la canalización almacenará algunos datos ...), pero mostrará la salida 1: 1 en la salida estándar tanto como en el archivo.

El único problema es que no pude resolverlo, es hacerlo desde una función, ya que abre una subshell, donde el ejecutivo no sirve para el programa principal ...

Este ejemplo redirige stdout y stderr sin perder el stdout y stderr original. También los errores en el controlador stdout se registran en el controlador stderr. Los descriptores de archivo se guardan en variables y se cierran en los procesos secundarios. Bash se encarga de que no se produzcan colisiones.

#! /bin/bash

stamp ()
{
  local LINE
  while IFS='' read -r LINE; do
    echo "$(date '+%Y-%m-%d %H:%M:%S,%N %z') $ $LINE"
  done
}

exec {STDOUT}>&1
exec {STDERR}>&2
exec 2> >(exec {STDOUT}>&-; exec {STDERR}>&-; exec &>> stderr.log; stamp)
exec > >(exec {STDOUT}>&-; exec {STDERR}>&-; exec >> stdout.log; stamp)

for n in $(seq 3); do
  echo loop $n >&$STDOUT
  echo o$n
  echo e$n >&2
done

Esto requiere una versión actual de Bash, pero gracias a Shellshock se puede confiar esto hoy en día.

Estaba buscando la misma cosita ordenada. Después de ver esta publicación, también vi otro enfoque que parece prometedor: http: //utcc.utoronto.ca/~cks/space/blog/unix/PipingJustStderr

cat q23123  2> tmp_file ;cat tmp_file | sed -e "s/^/$(date '+[%F %T]'): /g" >> output.log; rm -f tmp_file 
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top