0

I tried everything, but I still can't get the while loop to stop based on the following condition:

#!/bin/sh
clear
counter=1

breakCond=$(tail -n 1 /home/a/Desktop/Triple_Graphs/11_nodes/Res/Com_Output.txt|sed -r 's/^([^.]+).*$/\1/; s/^[^0-9]*([0-9]+).*$/\1/')
    
cd /home/a/Desktop/cliquer-1.21
rm /home/a/Desktop/Triple_Graphs/11_nodes/Res/Com_Output.txt
clear

Mu=$(head -1 /home/a/Desktop/Triple_Graphs/11_nodes/Mu.txt)
while [[ $counter -le 97 && $breakCond -ne $Mu ]]
do
#echo $counter| tee -a outErr.txt

    ./cl -u /home/a/Desktop/Triple_Graphs/11_nodes/G_$counter.txt &> /home/a/Desktop/Triple_Graphs/11_nodes/Res/calculated_$counter.txt
#echo -e "calculated_$counter.txt \n"

    output=$(tail -1 /home/a/Desktop/Triple_Graphs/11_nodes/Res/calculated_$counter.txt)

    echo $output>>/home/a/Desktop/Triple_Graphs/11_nodes/Res/Com_Output.txt

    ((counter++))

    breakCond=$(tail -n 1 /home/a/Desktop/Triple_Graphs/11_nodes/Res/Com_Output.txt|sed -r 's/^([^.]+).*$/\1/; s/^[^0-9]*([0-9]+).*$/\1/')
done

The second condition in my while loop does not work. I'm reading two values from txt files ("breakCond" and "Mu") and attempting to compare them.

tripleee
  • 175,061
  • 34
  • 275
  • 318
Arash
  • 225
  • 1
  • 11
  • 1
    Could you post a [minimal reproducible example](https://stackoverflow.com/help/minimal-reproducible-example)? There is no way to know what goes wrong with what you gave here. – Simon Doppler Mar 01 '22 at 07:58
  • 2
    If I put `counter=98` and `breakCond=$((Mu+1))` inside the loop, it exits after the first iteration. Without knowing what you have inside the loop, I have no idea why it doesn't work for you (or even why you expect it to exit). You really need to provide a [Minimal, Reproducible Example](https://stackoverflow.com/help/minimal-reproducible-example) here. – Gordon Davisson Mar 01 '22 at 08:02
  • @SimonDoppler I have updated my code. – Arash Mar 01 '22 at 08:10
  • Your tags and title say "Bash script" but your shebang says `#!/bin/sh`. Please review [Difference between `sh` and `bash`](https://stackoverflow.com/questions/5725296/difference-between-sh-and-bash) – tripleee Mar 01 '22 at 08:18
  • That's neither minimal nor reproducible -- nobody but you can try this out without a lot of other things (`./cl`, a number of files, etc) that shouldn't be needed to show the problem. If you replace the current stuff that sets `breakCond` with just `breakCond=$((Mu+1))`, does it exit after 97 iterations? – Gordon Davisson Mar 01 '22 at 08:22
  • @GordonDavisson when I use value insted of Mu it works fine `while [[ $counter -le 97 && $breakCond -ne 17 ]]` but with Mu i get syntax error `syntax error: invalid arithmetic operator (error token is` – Arash Mar 01 '22 at 08:28
  • Could you show us exactly what the first and last line are of those respective files which you build `breakCond` and `Mu` on. On top of that, could you also show us the values of `breakCond` and `Mu`. – kvantour Mar 01 '22 at 08:32
  • @kvantour Mu file contains only a number – Arash Mar 01 '22 at 08:37
  • @kvantour I also extracted the first number from this file `size=17, weight=17: 2 11 31 42 43 49 63 66 73 79 93 96 103 107 109 112 113` which is 17 here – Arash Mar 01 '22 at 08:38

1 Answers1

1

If you want to use Bash features, you need to make sure the script is executed by Bash. The precise location of Bash can vary, so I'll use env for portability here; but probably, you might want to hardcode e.g. #!/bin/bash to avoid this indirection.

Bash has built-in facilities for looping a specified number of times.

As a general design, I would remove the hard-coded absolute paths, and perhaps allow the user to override a built-in default. I also took out the apparently completely superfluous cd and the user-hostile clear. The current redesign simply assumes that you are running in /home/a/Desktop/Triple_Graphs/11_nodes so that you can run it in a different directory with sample data to test it.

#!/usr/bin/env bash

break_maybe () {
    # sed $!d replaces tail -n 1
    sed -r '$!d;s/^([^.]+).*$/\1/; s/^[^0-9]*([0-9]+).*$/\1/' "$1"
}

rm -f Res/Com_Output.txt

Mu=$(head -1 Mu.txt)

# {1..97} is Bash-specific
for counter in {1..97}; do
    if [[ $(break_maybe Res/Com_Output.txt) == "$Mu" ]]; then
        break
    fi
    /home/a/Desktop/cliquer-1.21/cl -u "G_$counter.txt" > "Res/calculated_$counter.txt" 2>&1
    tail -n 1 "Res/calculated_$counter.txt"
done >>Res/Com_Output.txt

I obviously have no way to test this, but it should at least suggest some ways to refactor this.

tripleee
  • 175,061
  • 34
  • 275
  • 318
  • Thank you for your answer, this also has the same issue which break condition not working – Arash Mar 01 '22 at 08:47
  • For example this works: `if [[ $(break_maybe Res/Com_Output.txt) == "17" ]]` – Arash Mar 01 '22 at 08:49
  • but I need to have the Mu as a variable. – Arash Mar 01 '22 at 08:50
  • 1
    Sounds like your file has some invisible characters, like probably DOS line endings. See also [Are shell scripts sensitive to encoding and line endings?](https://stackoverflow.com/questions/39527571/are-shell-scripts-sensitive-to-encoding-and-line-endings) Running with `bash -x` should reveal this. – tripleee Mar 01 '22 at 08:50
  • ` + bash -x Mu.txt + $'17\r' Mu.txt: line 1: $'17\r': command not found ` – Arash Mar 01 '22 at 09:00
  • 1
    Yeah, that `\r` is a DOS carriage return. (But normally you would run your _script_ with `bash -x`, not the text file!) – tripleee Mar 01 '22 at 09:17
  • I only need to run my script like `bash -x myscript.sh ?` – Arash Mar 01 '22 at 19:10
  • 1
    That's how you run it with debug tracing enabled; you probably need to spend some time familiarizing yourself with the output. – tripleee Mar 01 '22 at 19:41