views:

67

answers:

4

I would like to have a script wherein all commands are tee'd to a log file.

Right now I am running every command in the script thusly:

<command> | tee -a $LOGFILE

Is there a way to force every command in a shell script to pipe to tee?

I cannot force users to add appropriate teeing when running the script, and want to ensure it logs properly even if the calling user doesn't add a logging call of their own.

+2  A: 

Why not expose a wrapper that's simply:

/path/to/yourOriginalScript.sh | tee -a $LOGFILE

Your users should not execute (nor even know about) yourOriginalScript.sh.

Vinko Vrsalovic
A: 

Some approach would be creation of runner script "run_it" that all users invoke their own scripts.

run_it my_script

All the magic would be done within, e.g. could look like that:

LOG_DIR=/var/log/
$@ | tee -a  $LOG_DIR/
Gadolin
+6  A: 

You can do a wrapper inside your script:

#!/bin/bash
{
echo 'hello'
some_more_commands
echo 'goodbye'
} | tee -a /path/to/logfile

Edit:

Here's another way:

#!/bin/bash
exec > >(tee -a /path/to/logfile)
echo 'hello'
some_more_commands
echo 'goodbye'
Dennis Williamson
I like this one - hadn't thought about using brackets
warren
@warren: see my edit for another method.
Dennis Williamson
+1  A: 

Assuming that your script doesn't take a --tee argument, you can do this (if you do use that argument, just replace --tee below with an argument you don't use):

#!/bin/bash

if [ -z "$1" ] || [ "$1" != --tee ]; then
  $0 --tee "$@" | tee $LOGFILE
  exit $?
else
  shift
fi
# rest of script follows

This just has the script re-run itself, using the special argument --tee to prevent infinite recursion, piping its output into tee.

Adam Rosenfield