开发者

Logging functions in bash and stdout

I'd like to be able to put log messages in the middle of bash functions, without affecting the output of those very functions. For example, consider the following functions log() and get_animals开发者_运维百科():

# print a log a message
log ()
{
    echo "Log message: $1"
}

get_animals()
{
    log "Fetching animals"
    echo "cat dog mouse"
}

values=`get_animals`
echo $values

After which $values contains the string "Log message: Fetching animals cat dog mouse".

How should I modify this script so that "Log message: Fetching animals" is outputted to the terminal, and $values contains "cat dog mouse"?


choroba's solution to another question shows how to use exec to open a new file descriptor.

Translating that solution to this question gives something like:

# Open a new file descriptor that redirects to stdout:
exec 3>&1

log ()
{
    echo "Log message: $1" 1>&3
}

get_animals()
{
    log "Fetching animals"
    echo "cat dog mouse"
}

animals=`get_animals`
echo Animals: $animals

Executing the above produces:

Log message: Fetching animals
Animals: cat dog mouse

More information about using I/O redirection and file descriptors in Bash can be found at:

  • Bash Guide for Beginners, section 8.2.3, Redirection and file descriptors
  • Advanced Bash-Scripting Guide, Chapter 20, I/O Redirection


You can redirect the output to the sdterr error file on file handle 2 using >&2

example :

# print a log a message
log ()
{
echo "Log message: $1" >&2
}

get_animals()
{
log "Fetching animals"
echo "cat dog mouse"
}

values=`get_animals`
echo $values

the `` only take the output on stdout, not on stderr. The console on the other hand displays both.

If you really want the Log message on the stdout you can redirect error back to stdout after assigning to the variable :

# print a log a message
log ()
{
    echo "Log message: $1" >&2
}

get_animals()
{
    log "Fetching animals"
    echo "cat dog mouse"
}

values=`get_animals` 2>&1
echo $values


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


You could redirect log output to the standard error stream:

log()
{
    echo 1>&2 "Log message: $1"
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜