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 c...@case.edu http://cnswww.cns.cwru.edu/~chet/