2

I'm trying to define a bash function returning an incremented id that I can access directly using bash substitution:

#!/bin/bash

getId() {
        echo "$x"
        x=$((x+1))
}

x=0
echo "id1: $(getId)"
echo "id2: $(getId)"

However the variable is not incremented and I cannot figure out why.

id1: 0
id2: 0

Please, does someone have an explanation for this behaviour?

xsc
  • 5,983
  • 23
  • 30

3 Answers3

2
getId() {
  echo "$x"
  ((x++))
}
x=0
echo -n "id1: "
getId
echo -n "id2: "
getId

Output:

id1: 0
id2: 1
Cyrus
  • 84,225
  • 14
  • 89
  • 153
1

There is no easy way I know of to do it in a sub-shell call using the syntax you have (in the echo line).

An alternate would be:

#!/bin/bash

export x=0

incId() {
        #echo "$x"
        (( x += 1))
}

incId
echo "id1: $x"
incId
echo "id2: $x"

But here you need the out-of-the-echo-line incId function call to get the id incremented.

It also starts counting from 1, not 0.

Using the let shell command is the better way to do math too.

Using (( ... )) is the right way to do shell arithmetic

  • Thanks, you confirm that I'm not creazy and cannot do it in a one-line call. (and thanks for the let command) – user3149355 Apr 16 '15 at 17:26
  • `let` is an obsolete way to do math; `$((...))` is part of the POSIX standard. – chepner Apr 16 '15 at 17:36
  • Well, `((...))` is not POSIX; it's a bash extension, but for the most part `((x+=1))` is just short for `: $((x+=1))`. – chepner Apr 16 '15 at 17:57
  • Some ways to increment with bash: `x=0; : $[ x++ ]; ((x++)); x=$((x+1)); let x=x+1; echo $x` – Cyrus Apr 16 '15 at 18:11
1

Might as well make it generic:

incr() { (( $1 += ${2:-1} )); }

Examples:

incr x   ; echo $x  # => 1
incr x   ; echo $x  # => 2
incr x  4; echo $x  # => 6
incr x -2; echo $x  # => 4
glenn jackman
  • 238,783
  • 38
  • 220
  • 352