Path: csiph.com!xmission!news.glorb.com!usenet.stanford.edu!not-for-mail From: Linda Walsh Newsgroups: gnu.bash.bug Subject: Re: command substitution is stripping set -e from options Date: Mon, 12 Oct 2015 09:10:33 -0700 Lines: 86 Approved: bug-bash@gnu.org Message-ID: References: <560D83DA.9020405@redhat.com> <20151002122925.GK25574@eeg.ccf.org> <20151002132221.GL25574@eeg.ccf.org> <56103208.30406@case.edu> NNTP-Posting-Host: lists.gnu.org Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 7bit X-Trace: usenet.stanford.edu 1444666271 15850 208.118.235.17 (12 Oct 2015 16:11:11 GMT) X-Complaints-To: action@cs.stanford.edu Cc: Greg Wooledge , Christoph Gysin , bug-bash@gnu.org To: chet.ramey@case.edu Envelope-to: bug-bash@gnu.org User-Agent: Thunderbird In-Reply-To: <56103208.30406@case.edu> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x (no timestamps) [generic] X-Received-From: 173.164.175.65 X-BeenThere: bug-bash@gnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: Bug reports for the GNU Bourne Again SHell List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Xref: csiph.com gnu.bash.bug:11626 Chet Ramey wrote: > On 10/2/15 9:22 AM, Greg Wooledge wrote: >> On Fri, Oct 02, 2015 at 03:53:42PM +0300, Christoph Gysin wrote: >>> I'm still curious as to why set -e is stripped in the first place? >> Chet can give the definitive answer, but my take is that it's a huge >> surprise to someone writing a function independent of the script, or >> using a function that was written independently of the script. --- It used to not be so surprising before the action of set -e was changed to signal fail on non-simple commands returning non-zero return codes. Set -e used to be useful -- mostly during devel, but even in some "working" software to catch errors where the developer wasn't expecting a fail from some command. Having to write failure code for everything made set-e useless. A self-fulfilling truth, at the time, for those who argued that set-e was useless the way it previously functioned, so anything that changes its behavior should be considered a 'no-op', because it was already broken (for them). No one seemed to get the circular reasoning in use there. Before, auto-err-exit only happened on on **simple** (external) commands, but now builtins, like ((a=0));echo $? will trigger a exception with the ((a=0)) (because in calculations, a value of 0 is the only 'true' value. That was probably one of the more stupid effects of the new set-e changes -- that bash in non-posix mode should emulate the posix behavior and throw a errexit if a lone calculation yields 0, and made bash up to 22x slower on some numeric calcs 0) null case (no calculation) > time (i=1000000 && while((--i));do : ; done) 3.84sec 3.84usr 0.00sys (100.03% cpu) 1) simple calc, pre set-e change: > time (i=1000000 && while((--i));do ((a=0)); done) 3.92sec 3.91usr 0.00sys (100.01% cpu) simple calc - null case (removing loop costs) = .08s/1M-loops 2) using post set-o posix approved syntax: > time (i=1000000 && while((--i));do let a=0 ; done) 5.72sec 5.72usr 0.00sys (100.01% cpu) Posix pushed change in set-e case (minus null loop) = 1.88s/1M-loop or 22.5X the simple case. > It's been over 20 years, and we weren't as detailed with our change logs > back then, but I imagine the rationale was similar to the above with the > addition of something like the following: > > The parent shell (the one that enabled -e) should be the one to make the > decision about whether or not the shell exits. The exit status of the > command substitution doesn't make a difference except in one special case, > so inheriting errexit and exiting (possibly prematurely) doesn't really > help the parent decide whether or not to exit. --- Wasn't it still the case that an error in the function: could be caught in the parent by something like: funcall || { stat=$?; possible_altfunc or die $stat "msg" ;} --- > > Now, of course, it's been more than 20 years, and backwards compatiblity > is a concern. --- It wasn't so much, when set-e was changed only a few years ago. ;-/ Besides, what would be wrong with a env BASH_SETFLAG_MASK that could mask out set values that would auto-change in a function (or some similar mechanism). I had to write some workaround code to support '-x' staying on in functions, as well as having the effect of localizing any '-x' change to the function. (i.e. at beginning of function, restore global value of -x, at end of function restore previous global value again) Usually -- if I was tracing, I wanted to step into most functions, but I didn't want a function turning on tracing being propagated to the rest of the prog. -l