Search code examples
linuxbashshellscriptingcounter

Counter increment in Bash loop not working


I have the following simple script where I am running a loop and want to maintain a COUNTER. I am unable to figure out why the counter is not updating. Is it due to subshell that's getting created? How can I potentially fix this?

#!/bin/bash

WFY_PATH=/var/log/nginx
WFY_FILE=error.log
COUNTER=0
grep 'GET /log_' $WFY_PATH/$WFY_FILE | grep 'upstream timed out' | awk -F ', ' '{print $2,$4,$0}' | awk '{print "http://domain.example"$5"&ip="$2"&date="$7"&time="$8"&end=1"}' | awk -F '&end=1' '{print $1"&end=1"}' |
(
while read WFY_URL
do
    echo $WFY_URL #Some more action
    COUNTER=$((COUNTER+1))
done
)

echo $COUNTER # output = 0

Solution

  • First, you are not increasing the counter. Changing COUNTER=$((COUNTER)) into COUNTER=$((COUNTER + 1)) or COUNTER=$[COUNTER + 1] will increase it.

    Second, it's trickier to back-propagate subshell variables to the callee as you surmise. Variables in a subshell are not available outside the subshell. These are variables local to the child process.

    One way to solve it is using a temp file for storing the intermediate value:

    TEMPFILE=/tmp/$$.tmp
    echo 0 > $TEMPFILE
    
    # Loop goes here
      # Fetch the value and increase it
      COUNTER=$[$(cat $TEMPFILE) + 1]
    
      # Store the new value
      echo $COUNTER > $TEMPFILE
    
    # Loop done, script done, delete the file
    unlink $TEMPFILE