Force `tee` to run for every command in a shell script?
Asked Answered
C

4

5

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.

Chichi answered 27/10, 2010 at 19:59 Comment(0)
C
21

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'
Cantrip answered 27/10, 2010 at 20:20 Comment(2)
I like this one - hadn't thought about using bracketsChichi
Use exec > >(tee -a /path/to/logfile) 2>&1 to also output errors as well to the file in case you're doing a log of EVERYTHING that happens in one file. The -a is append, but you can also remove that to start fresh on the file every time.Luehrmann
F
2

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.

Foah answered 27/10, 2010 at 20:2 Comment(0)
R
2

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.

Refinement answered 27/10, 2010 at 20:42 Comment(1)
Could also use exec to not fork extra process: if ...; then exec $0 --tee "$@"; else; shift; fi (exit will not be needed any more)...Impassive
M
1

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/
Marjoriemarjory answered 27/10, 2010 at 20:17 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.