bash for loop

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • johny10151981
    Top Contributor
    • Jan 2010
    • 1059

    bash for loop

    Please someone explain me

    Code:
    #!/bin/bash
    
    ARRAY=("example program" "for test only" "Lets try");
    
    ELEMENTS=${#ARRAY[@]};
    
    echo $ELEMENTS;
    
    for((i=0;i<$ELEMENTS;i++));do
    echo ${ARRAY[$i]} # echo ${ARRAY[${i}]}
    done
    I know what i will get by executing this. got this from a website.
    But I dont understand how line 3 work.

    As well as the for loop required 2 first bracket "((...))".
    If I use one first bracket "(..)" it generates error.

    Can anyone explain these for me?

    Best regards,
    Johny
  • Oralloy
    Recognized Expert Contributor
    • Jun 2010
    • 988

    #2
    Johny,

    bash is a marvelously complex tool. And, it's still evolving, because it's so very useful.

    I've got quite a good tutorial book for it at home. It's a bit old, though, like 10 years or so. Still, I wish I could remember the title. It's one of the "Animal" books, though.

    Basically you need to use double parentheses because of other aspects of the bash syntax.

    Try looking up "bash for loop syntax" on google. It gives a good list of information.

    Comment

    • Nepomuk
      Recognized Expert Specialist
      • Aug 2007
      • 3111

      #3
      Hey there!

      OK, let's go through the code.
      Code:
      ARRAY=("example program" "for test only" "Lets try");
      This generates an array with the 3 elements "example program", "for test only" and "Lets try". Pretty easy.
      Code:
      ELEMENTS=${#ARRAY[@]};
      OK, there are a few things in this line. First of all, if you have a variable name, that may not be recognised as one (for example when accessing an array like here), you can put braces around the name. So, if you wanted to access the first element of the array, you would use ${ARRAY[1]}, as just $ARRAY[1] would resolve as example program[1]. (Note: if you access an array without a couter, it will always return the first element.)
      Next, the [@] part. The brackets behind the name of an array mean, that you want to access a certain element of that array. Putting an @ symbol there means, that you want to access all of the arrays elements. (Just like $@ means all of the arguments you gave, when calling the script.)
      Last but not least, the hash symbol (#). The hash symbol is quite commonly used to express the amount of something - and that is how bash uses it here. So, #ARRAY[@] means "give me the amount of elements in ARRAY[@]" (which as I said before gives you all elements in ARRAY).
      Code:
      echo $ELEMENTS;
      Gives you the number you just got.
      Code:
      for((i=0;i<$ELEMENTS;i++));do
      OK, for this you should know, that there are several forms of the for-loop in bash programming. Traditionally, you would use the form
      Code:
      for i in `seq $ELEMENTS`
      which works with basically all forms of shell (e.g. sh, ksh, csh, ...). If you already know how many times you want to go through the loop, you can also use the form
      Code:
      for i in {1..3}
      , but that didn't work for me when I tested using $ELEMENTS. In this case however, the programmer chose to use the C-like three-expression syntax. This form is easily understandable for anyone with a C-like background, but it's not very common in shell programming. Basically what happens is, that first a variable (i) is initialized, then there's a condition (i<$ELEMENTS) and then it is incremented (i++). The reason, that this whole thing has to be in double brackets is, that if you have single brackets, it's just a sequence of commands. For example,
      Code:
      (i=0; echo $i)
      will just output 0. Now, in pure bash syntax, i<$ELEMENTS doesn't make much sense - to test if the value of i is smaller than $ELEMENTS, you would normally write
      Code:
      [ $i -lt $ELEMENTS ]
      So, when this feature was introduced into bash syntax, they decided to use something they hadn't used before - double brackets.
      Oh, and the do starts a block of code, that the for loop should run.
      Code:
      echo ${ARRAY[$i]} # echo ${ARRAY[${i}]}
      The first echo will give you the i'th element of the Array for the reason I told you before. The second one won't do anything, as in this context the hash symbol starts a quote. The reason this quote was added is probably, because previously in the program, accessing variables was normally done with the braces and here he's not using them for the i. So, to show you that it's just a different way of doing the same thing, the programmer added the comment.
      Code:
      done
      This ends the block of code, which was started by do earlier.

      OK, hope this helped you. :-)

      Greetings,
      Nepomuk

      Comment

      • johny10151981
        Top Contributor
        • Jan 2010
        • 1059

        #4
        @ Nepomuk,
        thanks for your reply. you have given a great reply.

        But still I dont understand why

        for loop used nested bracket "((...))" single bracket generates error.

        Comment

        • Nepomuk
          Recognized Expert Specialist
          • Aug 2007
          • 3111

          #5
          OK, so in the double brackets it says
          Code:
          i=0;i<$ELEMENTS;i++
          In regular bash syntax, that would be a list of the 3 commands
          Code:
          i=0
          i<$ELEMENTS
          i++
          The i=0 isn't a problem, that's valid bash code. But if you enter i<$ELEMENTS into a bash shell, you'll get an error because it's invalid code. The correct way to compare those two values would be
          Code:
          [ $i -lt $ELEMENTS ]
          as I wrote in my previous post. The last command, i++ is similar - in standard bash, it doesn't make much sense. There are a few ways to increment a variable with regular bash syntax, e.g.
          Code:
          i=`expr $i + 1`
          or
          Code:
          i=$[i+1]
          or even
          Code:
          let i++
          but just i++ will give you an error message.

          So, as simple brackets just mean that you're listing a few commands in bash, listing those commands in single brackets will give you an error. That's why that version doesn't work.

          However, since bash 2.04 from what I read, bash also supports the so called "double parentheses construct". This basically allows C-style arithmetics to be used within double brackets (or "parenthese s"). You can find more details here, but basically you can use arithmetics within double brackets just like you would use them in any C-style language. The $ symbol before ELEMENTS makes bash replace that variable before running the arithmetics, so you get something like
          Code:
          i=0;i<3;i++
          which in C makes absolute sense. That's why in double brackets, it won't give you an error message.

          I hope that cleared up the situation for you. :-)

          Greetings,
          Nepomuk

          Comment

          Working...