Find the answer to your Linux question:
Results 1 to 9 of 9
Hello, I'm making a script (ksh) where I'm trying to call a function that I defined in the same script several times. I order to do that, I tried to ...
  1. #1
    Just Joined!
    Join Date
    Oct 2007
    Posts
    5

    Angry Function called only once in a "for" statement

    Hello,

    I'm making a script (ksh) where I'm trying to call a function that I defined in the same script several times. I order to do that, I tried to put it inside a "for" cycle as follows:

    for (cnt=0; cnt<10; cnt=cnt+1)
    do
    ...some code...
    MyFunction
    ...
    done

    ---------

    The intention is to call the function "MyFunction" repetitively.

    I noticed that MyFunction got called the first time (it entered the for cycle), but for some reason, once the function exits, the cycle is broken, and the script continues with the code after the "done" statement.

    In the example above, I would expect the script to call MyFunction 10 times, not only 1.

    Does anyone know if this is valid? If so, am I doing anything wrong?

    Thanks!

  2. #2
    Linux Engineer wje_lf's Avatar
    Join Date
    Sep 2007
    Location
    Mariposa
    Posts
    1,192
    Hmmm. That's strange. When I tried this script:
    Code:
    #!/bin/ksh
    
    for (cnt=0; cnt<10; cnt=cnt+1)
    do
      echo hi
    done
    all I got was this:
    Code:
    wally:~/friday$ h.sh
    ./h.sh: syntax error at line 3: `(' unexpected
    wally:~/friday$
    How could you have possibly gotten further?

    There's a piece of the puzzle that's missing here. Could you post a small script that demonstrates this for loop calling MyFunction once and only once?

  3. #3
    Just Joined!
    Join Date
    Oct 2007
    Posts
    22
    Your syntax is incorrect.

    Code:
    #!/bin/ksh
    
    for (( cnt=0; cnt<10; cnt=cnt+1 ))
    do
      echo hi
    done
    
    exit 0
    The above is a working script.

    I havent tested it, but I assume the missing parentheses are the cause of the OP's issues as well.

  4. #4
    Just Joined!
    Join Date
    Oct 2007
    Posts
    5
    Well yes, I just wanted you show more less what I was trying to do. Actually, its something like this:

    mylist=(a b c d e)

    for (( cnt=0; cnt<${#mylist[@]}; cnt++ )); do

    currentitem=${mylist[$((cnt))]}
    myFunction

    done

    -------------

    In here, "MyFunction" does something different, depending on the value of "currentitem".

    Any help is appreciated!

  5. #5
    Just Joined!
    Join Date
    Aug 2007
    Posts
    37
    The intention is to call the function "MyFunction" repetitively.

    I noticed that MyFunction got called the first time (it entered the for cycle), but for some reason, once the function exits, the cycle is broken, and the script continues with the code after the "done" statement.
    Maybe there's something wrong with 'myFunction' ?

    This seems to work okay:
    Code:
    #! /usr/bin/ksh
    
    myFunction() {
      case $currentitem in
        a)  echo "myFunction called" $((cnt+1)) "time   :  $currentitem"  ;;
        b)  echo "myFunction called" $((cnt+1)) "times  :  $currentitem"  ;;
        c)  echo "myFunction called" $((cnt+1)) "times  :  $currentitem"  ;;
        d)  echo "myFunction called" $((cnt+1)) "times  :  $currentitem"  ;;
        e)  echo "myFunction called" $((cnt+1)) "times  :  $currentitem"  ;;
      esac
    }
    
    mylist=(a b c d e)
    
    for (( cnt=0; cnt<${#mylist[@]}; cnt++ )); do
        currentitem=${mylist[${cnt}]}
        myFunction
    done
    Edit....I've altered '${mylist[$((cnt))]}' to '${mylist[${cnt}]}' as sixstringartist suggests in the next message.

  6. #6
    Just Joined!
    Join Date
    Oct 2007
    Posts
    22
    Yes, my post was referring to the post above mine in which he used incorrect syntax.

    Your for loop seems fine so perhaps you should post your function.

    Also, Im a bit confused by this syntax:
    Code:
    currentitem=${mylist[$((cnt))]}
    It works, but Ive never seen a variable referenced as $((var)). Why do you use that instead of ${mylist[${cnt}]}?

  7. #7
    Linux Enthusiast
    Join Date
    Aug 2006
    Posts
    631
    I should use a function with a parameter and a "for in" loop to loop through the items like this:

    Code:
    #!/bin/sh
    
    myFunction()
    {
      echo Item = $1
    }
    
    list="a b c d"
    
    for i in $list
    do
      myFunction $i
    done
    Regards

  8. #8
    Just Joined!
    Join Date
    Oct 2007
    Posts
    5
    Thanks a lot for your posts!!!

    There is no specific reason for the $((var)) convention. I saw it that way somewhere else and it worked for me. Changing it to what you suggested returns the same result. Something that is interesting to note here is that my script contains a bunch of "for/done" loops and they all work fine, except for the one that calls another function.

    I didn't want to go into many details because I thought my problem was more straightforward, but seeing that it's not here goes the rest of the story:

    "MyFunction" is actually a helper function that builds a directory list, based on the content of "currentitem". It is basically a set of "if/fi" pairs, as depicted below:

    if [[ $currentitem = "a" ]]; then
    directorylist=(
    /dir1/dir2
    /dir1/dir3
    /dir1/dir3/dir4
    )

    if [[ $currentitem = "b" ]]; then
    .....

    --------------

    However, inside every if/fi pair, I call another function that processes those directories. In short, the whole thing looks like this (please note that this will not compile, it has been shortened for easy reading):

    Code:
    main()
    {
    for (...)
    
    ...do something...
    MyFunction
    
    done
    }
    ##########
    
    MyFunction()
    {
    if [ currentitem = a ]; then
    directorylist= (...)
    Another_function()
    fi
    
    if [ currentitem = b ]; then
    directorylist= (...)
    Another_function()
    fi
    
    if [ currentitem = c ]; then
    directorylist= (...)
    Another_function()
    fi
    
    ...
    }
    
    ##########
    
    Another function()
    for (( cnt=0; cnt<${#directorylist[@]}; cnt++ )); do
    ...do something with the files in those directories...
    done
    }
    
    main $*
    # END OF SCRIPT
    --------------------------

    In the script above, in the main() function, if I comment "MyFunction", the loop is made withouth problems.

    When I uncomment it, the loop is executed once (only for the first "currentitem") and then it exits and continues with the rest of the script. This means that there were no errors (I set -e since the beginning of the script) and there were not "exit"/"return" calls either.

  9. #9
    Linux Enthusiast
    Join Date
    Aug 2006
    Posts
    631
    Try to run the script in debug mode with the -x option.

    Regards

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
...