Bash script does not continue after for loop

bash break out of for loop
do while loop in shell script
bash break nested loop
bash while loop
bash if statement
bash for loop
bash do while loop
bash break out of if

I am trying to make a mac Clippy in bash. Here is some of my code:

say "Hello there!"

declare -a assist_array=()

while true; do
  if pgrep -xq -- "Mail"; then
      assist_array+=('It looks like your trying to send an email. Would you like some help?')
  fi

  if pgrep -xq -- "Notes"; then
      assist_array+=('It looks like your trying to take a note. Would you like some help?')
  fi

  arraylength=${#assist_array[@]}
  for (( i=0; i<${arraylength}+1; i++ )); do
    echo ${assist_array[i]}
    say ${assist_array[i]}
    assist_array=()
  done

done

When I have Mail open, it echos and says: "It looks like your trying to send an email. Would you like some help?" then a new line. I have both Mail and Notes open. How can I make it so it continues to scan for open apps and not get stuck in the for loop?

You're emptying the array during the loop. As a result, when the next iteration is attempted, there's nothing in ${assist_array[i]} to print. If you need to empty the array, do it after the loop finishes.

Also, array indexes go from 0 to length-1, not from 1 to length. And you should generally quote variables that may contain multiple words.

for (( i=0; i<${arraylength}; i++ )); do
    echo "${assist_array[i]}"
    say "${assist_array[i]}"
done
assist_array=()

Bash Scripting Part2 – For and While Loops With Examples – Like , How do you run an infinite loop in shell script? Most of the time when running our script, we need not make any changes to it but sometimes need arises to control our loops. To achieve loop control, we use break or continue command depending on the need. Let’s discuss both commands in brief, BREAK command. Break command is used to exit out of current loop completely before the actual ending of loop.

say "Hello there!"

declare -a assist_array=()

while true; do
  if pgrep -xq -- "Mail"; then
      assist_array+=('It looks like your trying to send an email. Would you like some help?')
  fi

  if pgrep -xq -- "Notes"; then
      assist_array+=('It looks like your trying to take a note. Would you like some help?')
  fi

  arraylength=${#assist_array[@]}
  for (( i=0; i<${arraylength}; i++ )); do
    echo ${assist_array[i]}
    say ${assist_array[i]}    
  done
  assist_array=()
done

Above code should work for you. The issue is that arrays are zero based, so your reference to assist_array[2] is actually an empty string. When you pass nothing to "say", it will read stdin.

Also, as the other answers have indicated (either explicitly or implicitly) you are initializing the array inside the for loop. You shouldn't do that in as much as you are not done reading it yet.

So, basically, your just stuck with say waiting for stdin. You can hit Ctrl-D to end the stdin input on your current program.

Until Loop Shell Scripting, bin/bash # This script provides wisdom # You can now exit in a decent way. If no conversion needs to be done, a continue statement restarts execution of the  Another problem specific to bash is that SECONDS is incremented from 0 to 1 not after one second of bash starting but between 0 and 1 second after it was started. You may want to switch to ksh93 or zsh where that problem was fixed and which support floating point arithmetics and have builtin ways to sleep with subsecond granularity.

How to Run a Shell Script in Infinite Loop |, The break and continue loop control commands [1] correspond exactly to #!/bin​/bash LIMIT=19 # Upper limit echo echo "Printing Numbers 1 through 20 of this particular loop iteration. fi echo -n "$a " # This will not execute for 3 and echo # Exercise: # Come up with a meaningful use for "continue N" in a script. exit 0  The Bash way of using for loops is somewhat different from the way other programming and scripting languages handle for loops. Let's break the script down. Let's break the script down. In a BASH for loop, all the statements between do and done are performed once for every item in the list.

The shell's case statement allows you to execute an arbitrary code block based on whether or not a shell pattern can be matched against the value of a shell expansion. Chazelas even if I have become fairly good with it on my own right since. case pattern blocks are evaluated in order from first to last. The problem with the logic I’m having is I do not want the script to exit(as it does now) the loop once the file_system area reaches 60%. I want it to continue to retest bdf and continue the loop once disk usage drops below 60%.

The syntax of the continue statement is as follows: The following script prints numbers from 1 through 50 that are divisible by 9 . If a number is not divisible by 9 , the continue statement skips the echo  Mind that break exits the loop, not the script. This can be demonstrated by adding an echo command at the end of the script. This echo will also be executed upon input that causes break to be executed (when the user types "0"). In nested loops, break allows for specification of which loop to exit. See the Bash info pages for more.

In scripting languages such as Bash, loops are useful for automating We'll also show you how to use the break and continue statements to  See argument @ Bash FAQ entry #24: "I set variables in a loop. Why do they suddenly disappear after the loop terminates? Or, why can't I pipe data to read?" (most recently archived here). Summary: This is only supported from bash 4.2 and up. You need to use different ways like command substitutions instead of a pipe if you are using bash.

Comments
  • Wow! Three answers within 12 minutes of posting! I wish they had stack overflow when I started coding. Heck! I wish they had the internet when I started coding!
  • I know. Its wierd...
  • I ran it on my mac and I found it more annoying and less useful than the original clippy, so you have surpassed Microsoft. You may be interested in putting a sleep into your program to tone it down a little.
  • I did. This was just a clip of the program so the program could be replicated.