bug-bash
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Intriguing error with arithmetic evaluation


From: Chet Ramey
Subject: Re: Intriguing error with arithmetic evaluation
Date: Fri, 12 Aug 2016 14:22:32 -0400
User-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.11; rv:45.0) Gecko/20100101 Thunderbird/45.2.0

On 8/12/16 4:52 AM, NO REPLY wrote:

> Bash Version: 4.3
> Patch Level: 11
> Release Status: release
> 
> Description:
>       I have a few increment expressions used as ((level++)) and only one of 
> those is giving an error. When used with set -e, bash aborts
>       execution. Using ERR trap, I was able to identify the expression.
> 
> 
> Repeat-By:
> 
>       I have this simple logic in which I am running a sequence of commands 
> conditionally, based on what a user provided level is.
>       The intention is to only run those groups of commands appropriate for 
> the level specified. To demonstrate the idea, here is
>       a simple script:
> 
>       >>> CUT HERE <<<
>         #!/usr/bin/env bash
>         set -eEu -o pipefail
>        
>         trap 'echo "*** ERROR: Detected error on command: $BASH_COMMAND at 
> line: $LINENO"' ERR
>        
>         DEBUG_LEVEL=$1
>        
>         function debug_mode() {
>             declare -i level=0
>             (( level >= DEBUG_LEVEL )) || {
>                 echo "Running: level $((level+1)) commands"
>                 ((level++))
>             }
>             (( level >= DEBUG_LEVEL )) || {
>                 echo "Running: level $((level+1)) commands"
>                 ((level++))
>             }
>         }
>        
>         debug_mode
>       >>> CUT HERE <<<
> 
>       When this script works (as is the case on "GNU bash, version 
> 3.2.57(1)-release (x86_64-apple-darwin15)"), you would see the below 
> interaction:
> 
>       $ debug.sh 0
>       $ debug.sh 1
>       Running level 1 commands
>       $ debug.sh 2
>       Running level 1 commands
>       Running level 2 commands
> 
>       However, when run on this version of bash (or even on GNU bash, version 
> 4.1.2(1)-release (x86_64-redhat-linux-gnu)), the first "((level++))" results 
> in an error:
> 
>       $ debug.sh 0
>       $ debug.sh 1
>       Running: level 1 commands
>       *** ERROR: Detected error on command: ((level++)) at line: 8
> 
>       If I replace the first "((level++))" with ": $((level++))" or 
> "level+=1", then it goes through fine, and the second "((level++))" doesn't 
> generate any error.

The relevant change was probably the change in the set of commands to which
`set -e' applies.  The (( command (among others) was added to that list
in bash-4.1.  The change was the result of Posix changing the semantics
of the errexit option and expanding its scope from simple commands to
all commands.

The (( command returns 1 if the expression evaluates to 0.  When `level' is
0, level++ returns a 0 value, and (( returns a status of 1.

Chet
-- 
``The lyf so short, the craft so long to lerne.'' - Chaucer
                 ``Ars longa, vita brevis'' - Hippocrates
Chet Ramey, UTech, CWRU    chet@case.edu    http://cnswww.cns.cwru.edu/~chet/



reply via email to

[Prev in Thread] Current Thread [Next in Thread]