-1

I'm having a problem with my bash script about breaking out a nested while loop that reads a line from a logfile with tail.

What i need: The nested while loop that reads the logfile should find some regex. If that's true save it to a variable and break out the loop. Outside the loop there is a other while loop that checks if it's time to send some data over to a Confluence page. If it's not the time yet do nothing until a line is found in the while loop that is true to the regex.

I made a MVCE:

#!/bin/bash    

counterSearch=0    

tail -n0 -f $logfile | {
    while true; do
        currentMinute=$(date +%S)    

        # Checks if $currentSecond is set to 59. If true do something.
        # Else go back to while loop.
        if [[ $currentSecond -eq 59 ]]; then
           echo "Hello. This is 59 seconds outside while read line loop"
        fi

        # This while loop should always check if in the $logfile a specific line if found.
        # If true save it and go back to the outside while loop. When a new line is found
        # execute it again.
        while read line ; do
            if echo "$line" | grep -e "/rest/api/2/search.*PASSED" 1>/dev/null 2>&1 ; then
               echo "$date - Search and passed API action" >> $log
               counterSearch=$((counterSearch+1))
            fi
        done
    done
}    

The problem is that the keeps running the inner while loop. If doesn't break out to the outer while loop. I already tried it with functions and a function with an if/else that calls one or the other loop.

John Kugelman
  • 349,597
  • 67
  • 533
  • 578
Danny
  • 189
  • 2
  • 15
  • 1
    Related? [Modifying variable inside while loop is not remembered](http://stackoverflow.com/q/16854280/1983854) – fedorqui Aug 22 '16 at 12:42
  • I don't think so. He doesn't have to escape the while loop. I need the while loop only if a line is found otherwise nothing. – Danny Aug 22 '16 at 12:44
  • 1
    So, what's the problem with your code? Does it fail with an error? Does it not run like you expect? Don't just paste your code and expect us to figure out both the problem *and* the solution. – larsks Aug 22 '16 at 12:44
  • The problem is that the keeps running in the while loop. If doesn't break out to the outer while loop. I already tried it with functions and a function with a if else that calls one or the other loop. – Danny Aug 22 '16 at 12:46
  • Ok John. Is there any way to get out of the inner loop with something special? – Danny Aug 22 '16 at 12:46
  • 1
    You'll need to de-nest the loops and run one of them in the background. When the currentSecond check wants to quit it should kill the read line loop. (I would write up a proper answer, but I have to leave.) – John Kugelman Aug 22 '16 at 12:49
  • No problem. If you could, please. Thank you so far! – Danny Aug 22 '16 at 12:52
  • Or add a timeout with `read -t`. – John Kugelman Aug 22 '16 at 12:52
  • I guess two seperate scripts would be the best? – Danny Aug 22 '16 at 13:57

1 Answers1

-1

while loop is executed in a subshell

try this code:

#!/bin/bash    

export counterSearch=0    

tail -n0 -f $logfile | {
    while true; do
        currentMinute=$(date +%M)  
        currentSecond=$(date +%S)   

        # Checks if $currentSecond is set to 59. If true do something.
        # Else go back to while loop.
        if [[ $currentSecond -eq 59 ]]; then
           echo "Hello. This is 59 seconds outside while read line loop"
        fi

        # This while loop should always check if in the $logfile a specific line if found.
        # If true save it and go back to the outside while loop. When a new line is found
        # execute it again.
        while read line ; do
            if echo "$line" | grep -e "/rest/api/2/search.*PASSED" 1>/dev/null 2>&1 ; then
               echo "$date - Search and passed API action" >> $log
               export counterSearch=$((counterSearch+1))
            fi
        done
    done
}  
Ali Okan Yüksel
  • 338
  • 1
  • 13