== A Bash _test_ limitation and the brute force way around it Suppose that you are writing a Bash script (specifically Bash) and that you want to get a number from a command that may fail and might also {{ST:strike:return}} output '0' (which is a bad value here). No problem, you say, you can write this like so: .pn prewrap on > sz=$(zpool list -Hp -o size $pool) > if [ $? -ne 0 -o "$sz" -eq 0 ]; then > echo failure > .... > fi Because you are a smart person, you test that this does the right thing when it fails. Lo and behold: > $ ./scrpt badarg > ./scrpt: line 3: [: : integer expression expected At one level, this is a 'well of course'; _-eq_ specifically requires numbers on both sides, and when the command fails it does not output a number (in fact _$sz_ winds up empty). At another level it is very annoying, because what we want here is the common short-circuiting logical operators. The reason we're not getting the behavior we want is that _test_ (in the built in form in Bash) is parsing and validating its entire set of arguments before it starts determining the boolean values of the overall expression. This is not necessarily a bad idea ([[and _test_ has a bunch of smart argument processing ../unix/TestIsQuiteSmart]]), but it is inconvenient. (Note that Bash doesn't claim that _test_'s _-a_ and _-o_ operators are short-circuiting operators. In fact the idea is relatively meaningless in the context of _test_, since there's relatively little to short-circuit. A quick test suggests that at least some versions of Bash check every condition, eg _stat()_ files, even when they could skip some.) My brute force way around this was: > if [ $? -ne 0 -o -z "$sz" ] || [ "$sz" -eq 0 ]; then > .... > fi After all, _[_ is sort of just another program, so it's perfectly valid to chain _[_ invocations together with the shell's actual short circuiting logical operators. This way the second _[_ doesn't even get run if _$sz_ looks bad, so it can't complain about 'integer expression expected'. (This may not be the right way to do it. I just felt like using brute force at the time.) PS: Given that Bash emits this error message whether you like it or not, it would be nice if it had a _test_ operator for 'this thing is actually a number'. My current check here is a bit of a hack, as it assumes _zpool_ emits either a number or nothing. (Updated: minor wording clarification [[due to reddit https://www.reddit.com/r/commandline/comments/3atjk1/a_bash_test_limitation_and_the_brute_force_way/csg2iwx]], because they're right, 'return 0' is the wrong way to phrase that; I knew what I meant but I can't expect other people to.)