The test that gave up too early
- #bug-fix
- #conditionals
- #arithmetic
- #bash-compat
If one operand of a [[ ]] test is broken, bash says so and carries on
evaluating the rest. huck used to stop dead at the first problem, which changed
the answer whenever something later in the expression would have rescued it:
# before
$ x=@
$ [[ $x -eq 5 || 1 -eq 1 ]] && echo ok
huck: line 1: [[: @: syntax error: operand expected (error token is "@")# after
$ x=@
$ [[ $x -eq 5 || 1 -eq 1 ]] && echo ok
huck: line 1: [[: @: syntax error: operand expected (error token is "@")
okSame for !: a failed operand is just a non-zero result, so negating it gives
success. Beyond the wrong answer, abandoning the expression meant the surviving
branch was never evaluated at all — so a command substitution in it silently
did not run.
While in there, an unusable regular expression stopped announcing itself in somebody else's words:
# before
$ [[ a =~ [ ]]; echo "rc=$?"
huck: line 1: [[: regex error: regex parse error:
[
^
error: unclosed character class
rc=2# after
$ [[ a =~ [ ]]; echo "rc=$?"
rc=2bash prints nothing there. The old message was the Rust library huck is built on, talking directly to the user.
Numbers that were refused
Shell arithmetic reads a number the way C does, which means two things huck got wrong. A value too big for 64 bits wraps rather than failing:
# before
$ echo $((99999999999999999999))
huck: line 1: 99999999999999999999: integer literal out of range: 99999999999999999999
$ echo $((0xFFFFFFFFFFFFFFFF))
huck: line 1: 0xFFFFFFFFFFFFFFFF: hex literal out of range: 0xFFFFFFFFFFFFFFFF# after
$ echo $((99999999999999999999))
7766279631452241919
$ echo $((0xFFFFFFFFFFFFFFFF))
-1Until now -9223372036854775808 could not be written as a literal at all.
And a character the number's base cannot use belongs to the number, not to whatever follows it — so the complaint names the whole thing:
# before
$ echo $((12abc))
huck: line 1: 12abc: syntax error in expression (error token is "abc")# after
$ echo $((12abc))
huck: line 1: 12abc: value too great for base (error token is "12abc")Still open
Two findings from this pass are worth more than the fixes. Both started as "flaky test" and turned out to be real.
A multi-line command typed at the prompt intermittently never completes — about one run in five, on an idle machine, waiting forever rather than slowly (#722). And a coproc test fails two runs in eight standalone, not under load as previously recorded (#476).
Also open: an unmatched [ in a pattern should be an ordinary character, and
four of huck's five pattern consumers get that wrong — quietly, in case and in
${var#…} (#717).