🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: comp.unix.shell
Article #3983

Re: [tricky sh] how to log the stdout/stderr of a function ?

#3983
From: Brian Hiles
Date: Fri, 16 Nov 2001 19:47
162 lines
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-mail
References: <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