0

I am aware that I can log using tee

But I want to log from inside my script, at the same time display the content on the stdout.

Example, my code looks something like this:

    names=$(print("name1 name2 name3 name4"))

    for name in names
    do
       echo "Current Name: " $name 
       related_job= ps -ef | grep $name | awk '{print $9}' >> File.dat
       echo "related job: " $related_job
    done 

Now, this block will certainly echo at stdout, but I even want to log this to a log file, say script_name.log.

Also, I am calling the script through a scheduler and sue to come constraint I can't use script_name | tee log_file . I can just call the script by the script name.

What could be the solution to this?

chaos
  • 48,171

3 Answers3

1

If you are using bash, you can also combine bash's exec >&, to redirect all output from the script, with process substitution.

e.g. something like the following at the start of your script:

LOGFILE='/tmp/teelog.log'
savelog "$LOGFILE"
exec &> >(tee "$LOGFILE")

This will redirect both stdout & stderr to stdout and to $LOGFILE, using savelog to rotate and keep older logs (7 by default) every time the script is run.

cas
  • 78,579
  • ,This isn't working for me. As soon as i add the above line at the start of my script, the script gets stuck :( exec &> >(tee "$LOGFILE") is behaving very strangely, it is creating a ?? ( zero byte) file in the directory rather than the log file name i specify – NishantM Oct 06 '15 at 19:13
  • Is your script a bash script, and have you defined $LOGFILE? – cas Oct 06 '15 at 20:20
  • its ksh script , but i even tried with bash. And yes i did mention the file name in place of $LOGFILE – NishantM Oct 06 '15 at 21:06
0

Very simple; use tee with its option flags inside the script, not when you are calling the script.

At the end of any echo line, append | tee -a logfile

In place of any > file redirect, you can use | tee file to also send the text to stdout. (This overwrites the file instead of appending, just like the > file redirect.)

In place of any >> mylog.log redirect, you can use | tee -a mylog.log.

If you have many many lines involving output, I recommend making a simple function in your script to replace echo, which will look something like echo $* | tee -a logfile. (Not sure of the $* part; I haven't done a lot with functions within scripts.)

Wildcard
  • 36,499
0

tee might be what you want. Add this lines in the beginning of the script:

exec 1> >(tee -a logfile)
exec 2>&1

The first line redirects and appends (-a) everything from the standard ouput stream to the logfile and prints it to the screen. The second line redirects the standard error to standard output.


It is also possible with awk. Specially if you want the output to the screen, but logged with a date:

exec 1> >(awk -W interactive '{"date" | getline d; print $0; print d, $0 >> "logfile"}')
exec 2>&1

awk must be set to interactive, that awk writes unbuffered to standard output. If you want you can redirect the standard error to something different by (maybe another log file):

exec 2> >(...)
chaos
  • 48,171