Operating System - HP-UX
1752824 Members
4156 Online
108789 Solutions
New Discussion юеВ

How do you capture all terminal output resulting from running a script?

 
SOLVED
Go to solution
Kurt Renner
Frequent Advisor

How do you capture all terminal output resulting from running a script?

I am developing a script which will take our admins through the entire process of securing a HP-UX machine according to our corporate stds. I want a log file of all the activity performed within this script that can be used for later review in case there were problem areas in configuring the system.

One way I know I could do this is to use "tee" to write both to the terminal and to a log file. However, the scripting style I want to use is to call functions within an "if" statement. The functions will return 0 if successful, and non-zero if it is unsuccessful... similar to the following code.

if SomeFunction; then
State=/bin/true
else
State=/bin/false
fi

If I were to include a "| tee -a ${OutputFile}", it will skew the return code value of the function, and will always be true if the "tee" command is successful.

I could use tee in a pipeline when the script is initiated. I could also use the "script" command to capture it as well, but then every user would have to remember to invoke the script in one of these 2 ways... which wouldn't happen.

I tried putting the "script" command within the script, but as the man page says, I just get a spawned shell, and the script then proceeds after I exit the spawned shell... not capturing the output as I intend.

A good example of what I am trying to accomplish is the way the swintall command operates in non-interactive mode. All the terminal I/O is displayed to the user, and also captured in a file in the /var/adm/sw/ directory.

I'm looking to direct STDERR and STDOUT for the entire script, not individual commands, and to somehow do it within the script itself.

Any ideas would be appreciated.
Do it right the first time and you will be ahead in the long run.
13 REPLIES 13
Craig Rants
Honored Contributor

Re: How do you capture all terminal output resulting from running a script?

This may be what your looking for.

http://forums.itrc.hp.com/cm/QuestionAnswer/1,,0x6ac253921f1ad5118fef0090279cd0f9,00.html

GL,
C
"In theory, there is no difference between theory and practice. But, in practice, there is. " Jan L.A. van de Snepscheut
Pete Randall
Outstanding Contributor

Re: How do you capture all terminal output resulting from running a script?

Put a wrapper around the script - another script that invokes your original with stderr and stdout redirected.

Pete

Pete
harry d brown jr
Honored Contributor

Re: How do you capture all terminal output resulting from running a script?

Before you start the "secure" process, type in "script /tmp/filename", then proceed to do your magic. If you use Exceed, you can do the same by "ctrl-leftmousebutton" then select "log to file".



live free or die
harry
Live Free or Die
Robert Gamble
Respected Contributor

Re: How do you capture all terminal output resulting from running a script?

Here is an approach you might not have expected in this forum:

Try using a video/screen capture device using an xterm. You could voice over with the 'why', while the trainee see the commands being entered.

I know it seems a bit hollywood, but I've used many such training materials, and the trainees really benefit from the commentary and the examples.

Good Luck.
Pete Randall
Outstanding Contributor

Re: How do you capture all terminal output resulting from running a script?

Disregard previous response - after I thought about it for a minute, I realized that isn't going to do anything for you. Oh well.

Pete

Pete
Sanjay_6
Honored Contributor

Re: How do you capture all terminal output resulting from running a script?

Hi Kurt,

I think you are trying to capture the std output and the std err that gets displayed on the terminal when the script is run. Try this,

sh script >script.run.log 2>&1
or
./script >script.run.log 2>&1

Hope this helps.

regds
Bill Hassell
Honored Contributor

Re: How do you capture all terminal output resulting from running a script?

Probably the easiest way is to use script tracing (set -x or run the script as: sh -x script_name) and redirect STDERR to a file. Unfortunately, the default action for function calls is to turn off set -x so it would have to appear in every function too.

If you don't want all the trace statements, then you'll be best off writing a separate function for displaying all messages. So instead of writing:

echo "Enter new data: \c"

you would use (assumes $LOGFILE has already been defined):

LogWrite "Enter new data: \c"

and write a function like:

function LogWrite
{
print "$@" | tee -a $LOGFILE
}

And to capture non-zero exit codes seen by the shell put this trap statement at the beginning:

trap 'ErrWrite $0: A non-zero returncode occurred at line $LINENO' ERR

This trap statement will add the name of the script and the line number where any error return was detected. You may want to tee the error output into a different file such as $ERRLOG. The function ErrWrite would be:

function ErrWrite
{
print "$@" | tee -a $ERRLOG
}

For calls to processes that may return STDERR, you'll have to add: 2>>$LOGFILE (or 2>>$ERRLOG) to the end of each process call.


Bill Hassell, sysadmin
Steve Steel
Honored Contributor

Re: How do you capture all terminal output resulting from running a script?

Hi

As shown

script /tmp/file

Prompt will return

script

At end of script
exit

Prompt will return

All output to the screen is in /tmp/file

To debug the script if needed put set -x as
the first non comment line and all commands are also echoed as they are executed

steve steel
If you want truly to understand something, try to change it. (Kurt Lewin)
Kurt Renner
Frequent Advisor

Re: How do you capture all terminal output resulting from running a script?

Thanks a bunch for all the suggestions. I really like the quick responses I get when posting a question in this forum.

While I didn't use any of the ideas exclusively, I got a different idea from them, and thought I would share my solution:

Here's the code I put in the first part of the Main section of my script after all my function declarations:

: ${ScriptLog:="/tmp/${0##*/}.log"}; export ScriptLog
: ${FirstTimeThru:=/bin/true}; export FirstTimeThru

if ${FirstTimeThru}; then
test -f "${ScriptLog} && /usr/bin/mv ${ScriptLog} ${ScriptLog}.old || > ${ScriptLog}
export FirstTimeThru="/bin/false"
${0} $@ 2>&1 | tee -a ${ScriptLog}
else
exit $?
fi

I've tested this logic, and it gives me exactly what I was looking for. Thanks for all the suggestions!!!
Do it right the first time and you will be ahead in the long run.