0

I have a bash script with an if condition and continuous lines of script. However, after if condition nothing in the script seems to run. For example, here are the lines of script (The lines after continue in if condition are not reacting).

 dir=/usr/path/tofiles
    for file in $(find $dir -name \*txt)
    do
        fbase={file%.txt}
        if [ "$step" == "1" -a ! -f "${fbase}.header" ]
            then
                continue
        fi

    ### From here nothing in the script runs #####

        if [ -f "${fbase}merged" ]
        then
                echo "$file already merged"
        fi

       files="$files ${fbase}g.txt.gz"
       cnt=$(($cnt + 1))
       if [ "$cnt" -eq "$chunksize" ]
       then
           outid=$(uuidgen)
           logfile=${outdir}/${outid}.cluster.log
           echo "sh $(pwd)/mysecript.sh $outid $files"  
       fi
    done

After the first if condition nothing in the script is running, I tried printing using echo nothing is showing up. Precisely, the issue is after the continue statement within the if condition. Any help/suggestions are much appreciated.

Thanking you

ARJ
  • 2,021
  • 4
  • 27
  • 52
  • In case your first `if statement` is always `true` you'll always skip the rest of the loop (due to `continue`), so nothing else will be executed. – avermaet Jul 18 '19 at 10:18
  • I added a link with the infos you need. The official `bash` guide. – avermaet Jul 18 '19 at 10:34
  • 1
    From your comments at the other post, I'd like to tell you that it is also possible to use the `if statement` to check if some criteria is not true. You do it like `if [ ! condition ] `. So what you normally have in your `else` case implicitly, that the condition is not fulfilled, can be put as condition into the `if`. `!`means logical `NOT`. – avermaet Jul 18 '19 at 10:46
  • That's what I am doing in my if statement checking certain conditions using `IF NOT` (!) and `AND` (`-a`). My question is, after that condition the script is not jumping to next ` if-statement`. The `continue` within the `if-statement` is not functioning as it required to. – ARJ Jul 18 '19 at 10:53
  • Ok, so you need to nest your `if`s, which means that you go to the next statement if the first is `true`. Is this what you want? – avermaet Jul 18 '19 at 11:06
  • yes, but when i nest the `if's` then I will not get what I want. Else, what you asked is correct. – ARJ Jul 18 '19 at 12:38

2 Answers2

1

You seem to have a wrong interpretation of the continue statements.

The continue statement skips the lines below it and starts with the next iteration.

while (true) {
  print(1);
  if (true) {
    continue;
  }
  print(2);
}

In the above print(2) will never get executed as it skips it everytime and starts with the next iteration.

For deeper insight please read Nested-If statements in Shell-scripting

For your scenario please try this

dir=/usr/path/tofiles
    for file in $(find $dir -name \*txt)
    do
        fbase={file%.txt}
        if ! [ "$step" == "1" -a ! -f "${fbase}.header" ]
        then
            if [ -f "${fbase}merged" ]
            then
                echo "$file already merged"
            fi

            files="$files ${fbase}g.txt.gz"
            cnt=$(($cnt + 1))
            if [ "$cnt" -eq "$chunksize" ]
            then
                outid=$(uuidgen)
                logfile=${outdir}/${outid}.cluster.log
                echo "sh $(pwd)/mysecript.sh $outid $files"  
            fi
        fi
    done
iamsaksham
  • 2,879
  • 4
  • 26
  • 50
  • In this case, I need to go to the next `if loop` after the first one. How is it possible.Thanks – ARJ Jul 18 '19 at 10:22
  • @user1017373 You can use `if elseif` statements, so in case the first `if` is not true, it starts evaluating next `elseif` condition – iamsaksham Jul 18 '19 at 10:24
  • The script is bash shell. **This is not written in python**. – ARJ Jul 18 '19 at 10:28
  • @user1017373 oh, my bad dude. Use this link please https://stackoverflow.com/questions/5726839/nested-if-statements-in-shell-scripting – iamsaksham Jul 18 '19 at 10:30
  • @user1017373 I've edited my answer, please mark it as correct answer if you think it has guided you to the correct direction – iamsaksham Jul 18 '19 at 10:32
  • Ok, let me be more clear, I have an `if statement` to check all files, and if the files are not falling in the condition mentioned then I need my script go to next `if statement`, therefore I used `continue` (as it jumps into next iteration). I do not have any `else statement` within the same `if statement`. Hence, it should go to next `if statement ` and so on. However, this is not happening after the `continue`. – ARJ Jul 18 '19 at 10:35
  • @user1017373 i've edited my answer for your use, please have a look – iamsaksham Jul 18 '19 at 11:00
  • Ok, Thanks I do not want the second `if loop` within the first. That is not the case here. The script is I posted is part of a longer shell script. This nested loop will not suit my requrement. Thanks though. – ARJ Jul 18 '19 at 11:03
1

The problem with your script is, that in case your first if statement evaluates always to true you'll always skip the rest of the loop, due to the continue, so nothing else will be executed. This behavior is the same as in all other programming languages.

  • continue, like break, is a keyword to control the loop behavior. This means that using continueit is possible to skip the rest of the current loop iteration. And using break it is possible to exit the loop.

In case you need to go further to the next if statement, you need to nest your ifs, so that both are checked/evaluated.

More background information regarding this issue can be found here.

According to your comments, your code should include nested ifs, like:

dir=/usr/path/tofiles
  for file in $(find $dir -name \*txt)
  do
    fbase={file%.txt}

    if [ "$step" == "1" -a ! -f "${fbase}.header" ]
    then
      if [ -f "${fbase}merged" ]
      then
        echo "$file already merged"
      fi

      files="$files ${fbase}g.txt.gz"
      cnt=$(($cnt + 1))
      if [ "$cnt" -eq "$chunksize" ]
      then
        outid=$(uuidgen)
        logfile=${outdir}/${outid}.cluster.log
        echo "sh $(pwd)/mysecript.sh $outid $files"  
      fi
    fi
done
avermaet
  • 1,543
  • 12
  • 33