On Sat, 23 Oct 2010 20:03:05 -0400, Jameson Rollins <jroll...@finestructure.net> wrote: > On Sat, 23 Oct 2010 05:06:10 +0000, Clint Adams <sch...@debian.org> wrote: > > I think that that is a false analogy. I would liken it more to setting > > your bicycle to fall apart if ever it is ridden at a speed of exactly > > 5 miles per hour. > > I think that's an even falser analogy. Because we're using bash, we're > calling out to a lot of secondary processes. You really think the > program should just blithely continue running if one of those > subprocesses fails? I certainly don't. I think that's probably a > really bad idea, actually, especially when it means potentially locking > someone out of a machine, or opening it up to attack.
From what I can tell, nobody was suggesting that. > The assumption when using "set -e" is that if a call fails, it means > there's a problem. If we *expect* a call to return non-zero, or to > occasionally return non-zero, then we should be capturing it's return > code and acting accordingly. If we're not, then that's a bug. Exactly what is being suggested. > Your proposal to not use "set -e" would make everything much harder. > Not using "set -e" means we either just ignore all return codes, which I > already said I think is a bad idea, or we have to capture the return > code of *every* call, and check to make sure that it's returned what we > expect (which is usually just 0). That's a much more onerous task, and > one much more prone to failure. As it is now, we just have to capture > the return of the calls that we *expect* to occasionally return > non-zero. Nobody is suggesting that all return codes are ignored, so can we stop suggesting that as a possibility? Capturing the return code of every call and making sure it is what is expected isn't particularly onerous, its actually good practice. The fact that its not done, and instead "set -e" is used instead, is the reason why it seems onerous now. Its just good programming practice to look at the return code generated and decide what that means. In most cases a simple test to see if the return code is not zero will suffice. let a=0; echo $? The Bash FAQ[0] details one reason why 'set -e' fails in subtle and insidious ways, but an easy one is this: #!/bin/bash set -e let a=0 ; echo $? <EOF> You might expect the following to trigger an error, but it doesn't: #!/bin/bash set -e foo () { false; echo; } foo | echo <EOF> As the FAQ says, the goal of adding automatic error detection to the shell is non-trivial, and prone to unexpected results, that is because many commands are supposed to return non-zero. For example: if [ -d /foo ]; then ... else ... fi Clearly we don't want to abort when [ -d /foo ] returns non-zero (because the directory does not exist) -- this script wants to handle that in the else part. So the implementors decided to make a bunch of special rules, like "commands that are part of an if test are immune", or "commands in a pipeline, other than the last one, are immune". These rules are extremely convoluted, and they still fail to catch even some remarkably simple cases. Even worse, the rules change from one Bash version to another, as Bash attempts to track the extremely slippery POSIX definition of this "feature". When a SubShell is involved, it gets worse still -- the behavior changes depending on whether Bash is invoked in POSIX mode. There is an entire wiki that was created JUST for the purpose of trying to cover this in detail[1], the caveats are mind-numbingly onerous. Its far simplier, and far safer, to use your own error checking rather than try to learn all of these rules. micah 0. http://mywiki.wooledge.org/BashFAQ/105 1. http://fvue.nl/wiki/Bash:_Error_handling
pgpwrXu53Bis6.pgp
Description: PGP signature