tech-userlevel archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

RFC: Change to the way sh -x works ?

I am planning (well, have more or less implemented, but not committed)
a small change to the way "sh -x" works, to cause the trace output (from -x)
to continue appearing on the stderr that existed when the -x option was
turned on - rather than following stderr around as the script alters it.

An example of the effect ...

	andromeda$ ENV=/dev/null PS4='+ ' sh -x /tmp/tst
	+ exec 2>/dev/null

	andromeda$ ENV=/dev/null PS4='+ ' ./sh -x /tmp/tst
	+ exec 2>/dev/null
	+ test 0 -eq 1
	+ printf '%s\n' 'Usage: /tmp/tst log-file (with errors)' >&2
	+ exit 1

The ENV=/dev/null is just to avoid noise from my normal $ENV generating more
output.   /tmp/tst is a copy of an irrelevant script that is supposed
to be run with one arg - when it isn't (as here) it prints a usage message
and exits.   I modified it by inserting "exec 2>/dev/null" right at the
start of the script, which is why this demo uses a copy in /tmp instead
of the original (which is not called "tst"...)

The first invocation above (using "sh") is the old way.  Once the exec
command which moves stderr is performed, the tracing goes with it, so we
see no more trace lines.

The second ("./sh") is the new way, tracing continues on the stderr that
the shell started with (as the -x option was turned on on the command line.)

For this, stderr is remembered only when tracing turns from off to on,
if it is on already, and another "set -x" is performed, nothing changes.
That is deliberate, to avoid the trace output randomly moving around in
scripts that have "set -x" in them, but are then run with -x on the
command line (and similar effects).   To change the destination of tracing,
one needs to turn it off, then on again (eg: set +x -x 2>/tmp/newtrace).

And yes, if tracing is off, "set -x 2>/tmp/trace-file" works as expected
(tracing goes to the file in /tmp (in this example), the redirect is in
effect only for the "set" command, so after that, "normal" stderr is

Two questions.

Does anyone have any objection to (or suggestions for) this?

Would it be better to have this controlled by an option (perhaps -X ?)
so users/scripts can use whichever method they prefer, and if so, what
should the default setting be?


ps: this only applies to "-x" output, not that from the (superficially
similar) -v - mostly because (except when used as sh -nv script) I consider
the -v option largely as a waste of time, and in that one case where it
is useful, nothing actually gets executed (it is just a script syntax check)
so stderr can't be changed.

Home | Main Index | Thread Index | Old Index