views:

39

answers:

2

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"?

+6  A: 

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
Peter Tillemans
Yes, I know I *could* ... but I don't want to :-) To re-phrase, how can I deal with multiple stdouts in one script? One for the entire script and one for the function being called.
Adam
You cannot, because there are no multiple stdout's there is only 1. The presence of stdout and stderr is actually an old implementation of a pattern to separate payload from monitoring/instrumentation. The only ways to get the log() output to separate it from the payload or mark it so you can remove it afterwards : e.g. `get_animals | grep -v "^Log message:"` . Marking it and removing it is according to me even worse.
Peter Tillemans
Cool, OK I'll do that. I'd quite hoped I could reserve stderr for error output, and use stdout for logging output. I suppose the problem was between my keyboard and my chair :-)
Adam
+1  A: 

You could redirect log output to the standard error stream:

log()
{
    echo 1>&2 "Log message: $1"
}
Steve Emmerson
Yes, but I would like to log to stdout, not stderr.
Adam