0

It's my Bash script homework, I am confused about the output of my programs. Suppose I need to use script debugger.sh to invoke script program.sh until the second one failed, and capture all the output of program.sh

user@user-machine:~$ cat program.sh
#!/usr/bin/env bash

n=$(( RANDOM % 100 ))

if [[ n -eq 42 ]]; then
    echo "Something went wrong"
    >&2 echo "The error was using magic numbers"
    exit 1
fi

echo "Everything went according to plan"

user@user-machine:~$ cat debugger.sh
#! /bin/bash

touch info.txt
count=0

while [ 0 -eq 0 ]
do
    ./program.sh > info.txt
    if [ $? -eq 1 ]
    then
    echo "failed at stage $count" > info.txt
    break
    fi
    ((count++))
done

When I type command ./debugger.sh in my Bash shell, the result I expect:

user@user-machine:~$ ./debugger.sh
Something went wrong
user@user-machine:~$ cat info.txt
Everything went according to plan
Everything went according to plan
........
The error was using magic numbers
failed at stage....

But the actual result is:

user@user-machine:~$ ./debugger.sh
The error was using magic numbers
user@user-machine:~$ cat info.txt
failed at stage 199

I can't figure out where some output goes. Why "The error was using magic numbers" appears on my terminal, I think it should be redirected to the info.txt file. And the "Everything went according to plan" just vanish. It's so weird, can someone explain? My English is not so good, hope you guys understand. I'm really grateful to you guys.

1
  • Rather than while [ 0 -eq 0 ]; ... break; it would make sense to loop as long as the program is successful. In other words, just write while ./program.sh; do : $((count++)); done > info.txt; echo "Failed after $count successful runs"; Commented Jul 12, 2022 at 16:50

1 Answer 1

1

There are many unrelated errors here.

You are comparing the string n to 42, not the variable $n, so of course that will always fail.

You are overwriting the output file on each iteration, so you are overwriting the diagnostics from all previous iterations.

There are various other stylistic issues, many of which http://shellcheck.net/ will diagnose and often propose fixes for.

Your script uses Bash-only syntax in several places, so your question should not really be tagged ; see also Difference between sh and bash

All diagnostic messages are printed to standard error, and include the name of the responsible script.

Also, Why is testing “$?” to see if a command succeeded or not, an anti-pattern?

Here is a refactoring to hopefully address most of these issues.

#!/usr/bin/env bash

n=$(( RANDOM % 100 ))

if [[ $n -eq 42 ]]; then
    echo "$0: Something went wrong" >&2
    >&2 echo "$0: The error was using magic numbers"
    exit 1
fi

echo "Everything went according to plan"

The refactored debugging loop collects the results from every run. The log file includes the count, and captures both standard output and standard error.

#! /bin/bash

warn () {
    echo "$0: $*" >&2
}
die () {
    warn "$*"
    exit 1
}

count=0

# notice change
while true
do
    warn "run $count"
    ./program.sh ||
    die "failed at stage $count"
    ((count++))
done >info.txt 2>&1
Sign up to request clarification or add additional context in comments.

4 Comments

Thanks! You really help a lot. But I run few experiment both on if [[ $n -eq 42 ]] and if [[ n -eq 42 ]]. Then I get the same result, maybe It's a style problem. But It will cause error if we just use a single square bracket instead of two like if [ n -eq 42 ].
I try a lot and still can't figure out what cause the problem before your answer. But things becoming clear now. Thank you sir.
For those who don't understand 2>&1 well like me, this article may help. Understanding Shell Script's idiom: 2>&1
You're right, [[...]] provides an arithmetic context so the dollar sign is optional. TIL!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.