Article View: comp.unix.shell
Article #3983Re: [tricky sh] how to log the stdout/stderr of a function ?
From: Brian Hiles
Date: Fri, 16 Nov 2001 19:47
Date: Fri, 16 Nov 2001 19:47
162 lines
6592 bytes
6592 bytes
In comp.unix.shell Gael Trinquart <gaelt@yahoo.com> wrote:
> I try to log all the outputs of a sh function [ my_func | tee
> my_logfile ].
> my_func is defined and called from my_script and modifies variables
> defined in my_script.
> The problem with 'my_func | tee my_logfile' is that it creates a
> sub-shell where my_func has its own copy of my_script's variables.
> When my_func returns, the subshell exits and everything is logged fine
> BUT the modified variables are, of course, not taken into account.
> How can I log everything from my_func AND be able to modify
> my_script's variables ?
I can offhand think of three solutions:
(1) Start a script(1), and execute your script within, in substitution
of the external tee(1).
(2) Not knowing anything of the nature of quantity of output from your
function -- why not print out diagnostic output? I use:
eval "${DIAG:+echo >&2 diagnostic output... }"
Whenever envvar DIAG is set and non-null, one may see the output; otherwise,
the diagnostic code may be left inside the function.
(3) Again, without knowing the nature of the output you want; here is a
function to conditionally assert the "xtrace" shell option for ksh and sh.
This works better in ksh than sh for no other reason that in ksh shell
options (set -o ...) are local to the function. Otherwise, the function
is a kind of emulation of "typeset -ft foo" which specifies "xtrace" output
for function "foo".
#! /bin/echo error: only source
#*TAG:37255 5:Mar 19 1973:0644:xtrace:
# Author: Brian Hiles <bsh@iname.com>
# Copyright: (c) 2000
# Description: set or unset the shell xtrace option based on name of function
# Name: xtrace
# Project: @(#)xtrace.sh 1.2 1996/06 bsh@iname.com (Brian Hiles)
# Requires:
# Usage: xtrace [-0 argv0] [-c] [glob-pattern]
# Version: 1.02
#01
xtrace() # [-0 argv0] [-c] [glob-expr]
{ _oshopts=$-; set +x
OPTIND=1 _compl= _kludge=$0
while getopts :0:c _inst
do case $_inst in
0) _kludge=$OPTARG ;;
c) _compl=ON ;;
esac
done
set X "$@"; shift $OPTIND # do: shift `expr 0$OPTIND - 1`
eval "case '|${1-${XTRACE:-/}}|' in
*'|*|'*)
# unconditionally set xtrace
set -- -x -x ;;
'||') # unconditionally unset xtrace
set -- +x +x ;;
#XXX why ignore xtracing own function? will turn off xtracing anyway
#*'|xtrace|'*|*'|*/xtrace|'*)
## ksh88 bug: ignore xtracing of any file named 'xtrace'
## because $0 value in POSIX function is incorrect value.
##XXX will turn off xtracing for _all_ functions in pattern!
#set -- +x +x ;;
*) case \$_compl in
${1:-${XTRACE:-''}})
# globbing pattern matches current filename
set -- -x +x ;;
*) # ...else restore prior xtrace state
case \$_oshopts in
*x*) set -- -x -x ;;
*) set -- +x +x ;;
esac ;;
esac ;;
esac"
${_compl:+shift} # _complement decision to xtrace?
unset _compl _kludge _oshopts #_inst
set $1
}
#02 EMBEDDED MAN-PAGE FOR "src2man"
: '
#++
NAME
xtrace - set or unset the shell xtrace option based on $0
SYNOPSIS
xtrace [-0 argv0] [-c] [glob-pattern]
DESCRIPTION
"xtrace" is a generalized debugging facility to turn on, off, or
complement the "xtrace" option (-x) in the shell. An "xtrace"
invocation may be placed anywhere in the script, including within
functions (either POSIX or kornshell style.) When variable XTRACE,
which is in the form of a shell pattern, matches the current
script of function name, tracing will be asserted thenceforward
till the end of the function.
The optional pattern argument will override any value of XTRACE.
XTRACE=\* # unconditionally turn on xtracing.
XTRACE="" # unconditionally turn off xtracing.
#XXX
In Bourne shell, a "set -x" option will xtrace all functions.
In Kornshell, to xtrace a function, command "typeset -ft <name>".
Note that "$0" initially contains the name of the shell in an
interactive environment, perhaps with a leading dash indicating
a login shell, and perhaps in the format of a full pathname.
Your pattern will need to match these potential contigencies.
OPTIONS
-0 name - The argument <name> will be used instead of $0.
XXXThis option must be the first option.
XXXand <argv> must exist as a separate parameter. (See: BUGS)
-c - Complements the filename pattern match; this will not
affect the unconditional setting or unsetting of xtrace.
EXAMPLE
#XXX will xtrace be asserted in POSIX beyond function execution?
In Kornshell 1993: if there is an "xtrace" call in functions "foo",
"bar", and "baz", place the following code at the top of the shprog:
for fn in foo bar baz
do alias $fn="PS4='[$fn:\$LINENO]' XTRACE=\\* $fn"
done
The above will work equally well in kornshell-type as well as in
POSIX functions, unlike the technique of "typeset -ft foo bar baz".
Refer also to the script $SIDEROOT/demo/xtrace.demo.
ENVIRONMENT
XTRACE="*" - sets xtrace for all scripts
XTRACE= - unsets xtrace for all scripts
XTRACE=shprog - sets xtrace for script "shprog"
XTRACE="prog[12]" - sets xtrace for scripts "prog1" and "prog2"
SEE ALSO
ppp(3S), pppw(3S)
BUGS
A ksh88 bug: function "xtrace" ignores xtracing of any script
or function named "xtrace" because in a POSIX function the $0
value is supposed to be the value of the script name instead of
the function name. As ksh88 gets this wrong, the "-0" option
exists to work around this via an alias:
alias xtrace="xtrace -0 \$0"
Options and option arguments must be separated by whitespace. XXX
Unsetting a preset xtrace leaves an unavoidable artifact in Bourne.
#--
'
=Brian
Technical Details
Message-ID:
<tvaranb0v78h18@corp.supernews.com>Path:
arc1-ca.pugleaf.net!archiver1.google.com!news1.google.com!sn-xit-02!sn-post-01!supernews.com!corp.supernews.com!not-for-mailReferences:
<50c0d466.0111161104.55629336@posting.google.com>Show Full Headers
Complete Article Headers
X-Google-Language: ENGLISH,ASCII-7-bit
X-Google-Thread: fc89c,7f27c6718083ef6e
X-Google-Attributes: gidfc89c,public
X-Google-Thread: 110f2c,7f27c6718083ef6e
X-Google-Attributes: gid110f2c,public
X-Google-Thread: 1012a6,7f27c6718083ef6e
X-Google-Attributes: gid1012a6,public
X-Google-ArrivalTime: 2001-11-16 11:47:35 PST
Path: arc1-ca.pugleaf.net!archiver1.google.com!news1.google.com!sn-xit-02!sn-post-01!supernews.com!corp.supernews.com!not-for-mail
From: Brian Hiles <bsh@rawbw.com>
Newsgroups: comp.unix.shell,comp.unix.programmer,fr.comp.os.unix
Subject: Re: [tricky sh] how to log the stdout/stderr of a function ?
Date: Fri, 16 Nov 2001 19:47:35 -0000
Message-ID: <tvaranb0v78h18@corp.supernews.com>
References: <50c0d466.0111161104.55629336@posting.google.com>
User-Agent: tin/1.4.4-20000803 ("Vet for the Insane") (UNIX) (FreeBSD/4.2-STABLE (i386))
X-Complaints-To: newsabuse@supernews.com
Lines: 162