ver tipos tiempo real logs log ejemplos contenido comandos comando basicos archivo bash shell unix redirect

bash - tipos - ver el contenido de un archivo en linux



Escritura de salidas para archivo de registro y consola (9)

En shell Unix, tengo un archivo env (archivo env define los parámetros necesarios para ejecutar el script del usuario como nombre de archivo de registro y ruta, redirigir salidas y errores al archivo de registro, detalles de conexión de base de datos, etc. ) que redirige todas las salidas ( mensajes de eco ) y errores en el archivo de registro del script ejecutado utilizando el siguiente código:

exec 1>>${LOG_FILE} exec 2>>${LOG_FILE}

El archivo env se ejecuta al comienzo de cada script. Debido al código anterior en el archivo env, todas las salidas de la consola que pueden ser salidas del usuario o errores se envían directamente al archivo de registro, que es lo que realmente necesitaba.

Pero hay algunas salidas de usuario selectivas que quiero que se muestren tanto en la consola como en el archivo de registro. Pero debido al código anterior, no puedo hacerlo.

Sé que si elimino el código anterior, puedo obtener el resultado deseado para este caso, pero tendré que escribir manualmente todas las demás salidas en el archivo de registro, lo cual no es una tarea fácil.

¿Hay alguna manera de obtener el resultado tanto en la consola como en el archivo de registro sin eliminar los códigos anteriores?


Encuentro muy útil agregar tanto stdout como stderr a un archivo de registro. Me alegré de ver una solución de alfonx con exec > >(tee -a) , porque me preguntaba cómo lograr esto usando el exec . Me encontré con una solución creativa que usa la sintaxis here-doc y . : https://unix.stackexchange.com/questions/80707/how-to-output-text-to-both-screen-and-file-inside-a-shell-script

Descubrí que en zsh, la solución here-doc se puede modificar utilizando el constructo "multios" para copiar la salida a stdout / stderr y al archivo de registro:

#!/bin/zsh LOG=$0.log # 8 is an arbitrary number; # multiple redirects for the same file descriptor # triggers "multios" . 8<</EOF /dev/fd/8 2>&2 >&1 2>>$LOG >>$LOG # some commands date >&2 set -x echo hi echo bye EOF echo not logged

No es tan legible como la solución exec , pero tiene la ventaja de permitirle registrar solo una parte del script. Por supuesto, si omite el EOF, todo el script se ejecuta con el registro. No estoy seguro de cómo zsh implementa multios, pero puede tener menos gastos generales que tee . Desafortunadamente parece que uno no puede usar multios con exec .


He encontrado una forma de obtener el resultado deseado. Aunque puede ser de alguna manera poco ortodoxa. De todos modos aquí va. En el archivo redir.env tengo el siguiente código:

#####redir.env##### export LOG_FILE=log.txt exec 2>>${LOG_FILE} function log { echo "$1">>${LOG_FILE} } function message { echo "$1" echo "$1">>${LOG_FILE} }

Luego, en el guión real, tengo los siguientes códigos:

#!/bin/sh . redir.env echo "Echoed to console only" log "Written to log file only" message "To console and log" echo "This is stderr. Written to log file only" 1>&2

Aquí, echo sale solo a la consola, registra las salidas para solo registrar el archivo y las salidas de mensajes tanto para el archivo de registro como para la consola.

Después de ejecutar el archivo de script anterior, tengo los siguientes resultados:

En la consola

En la consola
Echoed to console only
Para consolar y registrar

Para el archivo de registro

En archivo de registro escrito solo para el archivo de registro
Esto es stderr Escrito solo para el archivo de registro
Para consolar y registrar

Espero que esto ayude.


Intenté la respuesta de Joonty, pero también obtuve

ejecutivo: 1: no encontrado

error. Esto es lo que funciona mejor para mí (se confirmed que también funciona en zsh):

#!/bin/bash LOG_FILE=/tmp/both.log exec > >(tee -a ${LOG_FILE} ) exec 2> >(tee -a ${LOG_FILE} >&2) echo "this is stdout" chmmm 77 /makeError

El archivo /tmp/both.log contiene luego

this is stdout chmmm command not found

El /tmp/both.log se agrega a menos que elimine el -a del tee.


Prueba esto, hará el trabajo:

log_file=$curr_dir/log_file.txt exec > >(tee -a ${log_file} ) exec 2> >(tee -a ${log_file} >&2)


Quería mostrar los registros en stdout y el archivo de registro junto con la marca de tiempo. Ninguna de las respuestas anteriores funcionó para mí. Hice uso de la sustitución de procesos y el comando exec y se me ocurrió el siguiente código. Registros de muestra:

2017-06-21 11:16:41+05:30 Fetching information about files in the directory...

Agregue las siguientes líneas en la parte superior de su secuencia de comandos:

LOG_FILE=script.log exec > >(while read -r line; do printf ''%s %s/n'' "$(date --rfc-3339=seconds)" "$line" | tee -a $LOG_FILE; done) exec 2> >(while read -r line; do printf ''%s %s/n'' "$(date --rfc-3339=seconds)" "$line" | tee -a $LOG_FILE; done >&2)

Espero que esto ayude a alguien!


Sí, quieres usar tee :

tee - leer desde entrada estándar y escribir en salida estándar y archivos

Simplemente canalice su comando a la T y pase el archivo como un argumento, de esta manera:

exec 1 | tee ${LOG_FILE} exec 2 | tee ${LOG_FILE}

Esto imprime la salida a STDOUT y escribe la misma salida en un archivo de registro. Ver man tee para más información.

Tenga en cuenta que esto no escribirá stderr en el archivo de registro, por lo que si desea combinar las dos secuencias, utilice:

exec 1 2>&1 | tee ${LOG_FILE}


para el archivo de registro puede fechar para ingresar datos de texto. El siguiente código puede ayudar

# declaring variables Logfile="logfile.txt" MAIL_LOG="Message to print in log file" Location="were is u want to store log file" cd $Location if [ -f $Logfile ] then echo "$MAIL_LOG " >> $Logfile else touch $Logfile echo "$MAIL_LOG" >> $Logfile fi

salida: 2. El archivo de registro se creará en la primera ejecución y continuará actualizando desde las siguientes ejecuciones. En caso de que falte el archivo de registro en una ejecución futura, el script creará un nuevo archivo de registro.


# #------------------------------------------------------------------------------ # echo pass params and print them to a log file and terminal # with timestamp and $host_name and $0 PID # usage: # doLog "INFO some info message" # doLog "DEBUG some debug message" # doLog "WARN some warning message" # doLog "ERROR some really ERROR message" # doLog "FATAL some really fatal message" #------------------------------------------------------------------------------ doLog(){ type_of_msg=$(echo $*|cut -d" " -f1) msg=$(echo "$*"|cut -d" " -f2-) [[ $type_of_msg == DEBUG ]] && [[ $do_print_debug_msgs -ne 1 ]] && return [[ $type_of_msg == INFO ]] && type_of_msg="INFO " # one space for aligning [[ $type_of_msg == WARN ]] && type_of_msg="WARN " # as well # print to the terminal if we have one test -t 1 && echo " [$type_of_msg] `date "+%Y.%m.%d-%H:%M:%S %Z"` [$run_unit][@$host_name] [$$] ""$msg" # define default log file none specified in cnf file test -z $log_file && / mkdir -p $product_instance_dir/dat/log/bash && / log_file="$product_instance_dir/dat/log/bash/$run_unit.`date "+%Y%m"`.log" echo " [$type_of_msg] `date "+%Y.%m.%d-%H:%M:%S %Z"` [$run_unit][@$host_name] [$$] ""$msg" >> $log_file } #eof func doLog


exec 3>&1 1>>${LOG_FILE} 2>&1

enviaría salida stdout y stderr al archivo de registro, pero también te dejaría con fd 3 conectado a la consola, por lo que puedes hacer

echo "Some console message" 1>&3

escribir un mensaje solo a la consola, o

echo "Some console and log file message" | tee /dev/fd/3

para escribir un mensaje tanto en la consola como en el archivo de registro: tee envía su salida a su propio fd 1 (que aquí es el LOG_FILE ) y al archivo que le indicó que escribiera (que aquí es fd 3, es decir, la consola) .

Ejemplo:

exec 3>&1 1>>${LOG_FILE} 2>&1 echo "This is stdout" echo "This is stderr" 1>&2 echo "This is the console (fd 3)" 1>&3 echo "This is both the log and the console" | tee /dev/fd/3

imprimiría

This is the console (fd 3) This is both the log and the console

en la consola y poner

This is stdout This is stderr This is both the log and the console

en el archivo de registro.