Date: Sun, 12 Nov 2017 15:34:55 -0500 From: chris...@zoulas.com (Christos Zoulas) Message-ID: <20171112203456.0380117f...@rebar.astron.com>
| | Two different "enable trace" options would be a mess, and wouldn't work | | all that well (what do we do if both are enabled?) | | Error out, ignore the second? No, I don't think so, either would be ugly -- and just ignoring changes to -x because -X happens to be set has the potential to break things more badly then the previous proposal ever had, and generating an error would make -X impossible to use with some scripts, for no good reason. I have a slightly different idea to suggest instead (this one is not yet fully implemented, it is more complex than the previous, so no demo, but I think it will be easy enough to understand how it should work.) First, "set -x" stays as it has been in the past, and enables/disables tracing, and if nothing else is done, follows stderr around as it is changed (each trace message will go to whatever happens to be stderr at the time it is generated). Anything currently using -x, will see no differences. [ An aside; just to clarify something which is not changing - tracing happens before any redirects on the command line, so (assuming -x is set) "echo foo 2>/dev/null" does not send the trace output for the echo command to /dev/null, but "{ echo foo ;} >/dev/null does. That does not make it silent wrt tracing however, as the { } compound is still traced, at least in netbsd-8/current sh. ] To this a new -X (aka Xtrace) option is added - think of it as a "super x", or to use 1940's/1950's British terminology, for at least some classes of Brits of the era, "capital x"... (I think ... that's a bit before my time, and not my country, and not quite the way the idiom would have been expressed.) Any change to -X is also (immediately after) performed on -x as well (the sequencing is important). But in addition to turning on command tracing (when enabled by "set -X" or -X on the command line), this option also locks the trace output to go to whatever stderr is at the time the X option is turned on. This time the intent will be that any time "set -X" is done, stderr at the time will become the trace destination - since nothing is currently using this option (as it does not yet exist) there is no need to deal with unintentional manipulation in existing scripts, which was the motivation for the "only when going from off to on" that was in the previous proposal, and which was a bit ugly, and which had a special case exception I never bothered to mention... and now never need to.) Existing scripts that want to manipulate (turn on/off) tracing, will work just fine with this, $- will show the 'x' option set whenever tracing is enabled, and clear when it isn't, and set -x or set +x can be used to enable/disable tracing regardless of whether -X is set or not. $- will also show the X option if that is set, but existing scripts will have no idea what that means, and should just leave it alone. What won't work is saving options with "set +o" and restoring them later - the options will be saved/restored just fine, but there is no way to work out where stderr is being sent (ie: the path name) in order to get that back again later (consider "sh -X 2>/tmp/trace-file script" where "script" then uses "set +o" to save the options, and either it, or even some other script being run by a different instance of sh, later executes the output from the "set +o" to restore the options - all sh knows is "stderr is directed to some file somewhere..." it cannot supply a file name.) Of course, the previous proposal had that problem as well. When Xtrace is disabled ("set +X"), tracing is disabled (this does "set +x" as a side effect) and then if later enabled again using "set -x" the trace output will go back to being to whatever is current stderr. The idea is that users who want the new style, can just use -X/+X as a direct replacement for -x/+x (unless they want to do something fancy, in which case making use of both the X and x options could be required.) Does this seem more reasonable (or safer) than the previous suggestion ? kre ps: I did not think to mention the last time, but in both that proposal, and this one, if a function contains "local -" (ie: option changes are local to the function) then when the function returns, any changes to -x (or -X) that occurred during the function (after that local command, of course), including any changes to where the tracing gets sent, will be undone (tracing will go back to where it was being sent before the function changed it, if it did -- "local -" is more often used in functions that change "-f" or "-e" and similar, than those that are playing with -x.)