Programing

로그 파일 및 콘솔에 출력 쓰기

lottogame 2020. 9. 18. 19:15
반응형

로그 파일 및 콘솔에 출력 쓰기


유닉스 쉘에서 나는 (A ENV 파일이 ENV 파일은 파일, 데이터베이스 연결 정보 등을 기록하는 로그 파일의 이름과 경로, 리디렉션 출력 및 오류 등 사용자 스크립트를 실행하는 데 필요한 매개 변수를 정의합니다 () 모든 출력을 리디렉션하는 에코 메시지를 ) 및 다음 코드를 사용하여 실행 된 스크립트의 로그 파일에 오류가 있습니다.

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

env 파일은 각 스크립트의 시작 부분에서 실행됩니다. env 파일의 위 코드로 인해 사용자 출력 또는 오류 일 수있는 모든 콘솔 출력이 실제로 필요한 로그 파일에 직접 출력됩니다.

그러나 콘솔과 로그 파일 모두에 표시하려는 선택적 사용자 출력이 있습니다. 그러나 위의 코드 때문에 그렇게 할 수 없습니다.

위의 코드를 제거하면이 경우에 원하는 결과를 얻을 수 있지만 다른 모든 출력을 로그 파일에 수동으로 작성해야하는 것은 쉬운 일이 아닙니다.

위의 코드를 제거하지 않고 콘솔과 로그 파일 모두에서 출력을 얻는 방법이 있습니까?


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

stdout 및 stderr 출력을 로그 파일로 보내지 만 fd 3이 콘솔에 연결된 상태로 두어도됩니다.

echo "Some console message" 1>&3

콘솔에만 메시지를 쓰거나

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

콘솔 로그 파일 모두 에 메시지를 쓰려면 - 출력을 자체 fd 1 (여기서는 )과 작성하도록 지시 한 파일 (여기서는 fd 3, 즉 콘솔)로 보냅니다 .teeLOG_FILE

예:

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

인쇄 할 것이다

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

콘솔에 넣고

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

로그 파일에.


예, 다음을 사용합니다 tee.

tee-표준 입력에서 읽고 표준 출력 및 파일에 쓰기

다음과 같이 명령을 tee에 파이프하고 파일을 인수로 전달하십시오.

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

이것은 둘 다 출력을 STDOUT에 인쇄하고 동일한 출력을 로그 파일에 기록합니다. 자세한 내용은를 참조하십시오 man tee.

이것은 로그 파일에 stderr를 쓰지 않으므로 두 스트림을 결합하려면 다음을 사용하십시오.

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

나는 Joonty의 대답을 시도했지만

exec : 1 : 찾을 수 없음

오류. 이것은 나에게 가장 잘 작동하는 것입니다 ( 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

이후의 /tmp/both.log 파일에는

this is stdout
chmmm command not found 

tee에서 -a를 제거하지 않으면 /tmp/both.log가 추가됩니다.

힌트 : >(...)프로세스 대체입니다. 그것은을 할 exec받는 사람 tee이 파일 인 것처럼 명령.


I wanted to display logs on stdout and log file along with the timestamp. None of the above answers worked for me. I made use of process substitution and exec command and came up with the following code. Sample logs:

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

Add following lines at the top of your script:

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)

Hope this helps somebody!


for log file you may date to enter into text data. following code may help

# 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  

ouput: 2. Log file will be created in first run and keep on updating from next runs. In case log file missing in future run , script will create new log file.


I have found a way to get the desired output. Though it may be somewhat unorthodox way. Anyways here it goes. In the redir.env file I have following code:

#####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}
    }

Then in the actual script I have the following codes:

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

Here echo outputs only to console, log outputs to only log file and message outputs to both the log file and console.

After executing the above script file I have following outputs:

In console

In console
Echoed to console only
To console and log

For the Log file

In Log File Written to log file only
This is stderr. Written to log file only
To console and log

Hope this help.


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

I find it very useful to append both stdout and stderr to a log file. I was glad to see a solution by alfonx with exec > >(tee -a), because I was wondering how to accomplish this using exec. I came across a creative solution using here-doc syntax and .: https://unix.stackexchange.com/questions/80707/how-to-output-text-to-both-screen-and-file-inside-a-shell-script

I discovered that in zsh, the here-doc solution can be modified using the "multios" construct to copy output to both stdout/stderr and the log file:

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

It is not as readable as the exec solution but it has the advantage of allowing you to log just part of the script. Of course, if you omit the EOF then the whole script is executed with logging. I'm not sure how zsh implements multios, but it may have less overhead than tee. Unfortunately it seems that one cannot use multios with exec.


Try this, it will do the work:

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

참고URL : https://stackoverflow.com/questions/18460186/writing-outputs-to-log-file-and-console

반응형