A question for the experts: In my scripts it occasionally happens that I need a conditional (if ... then) jump to the beginning of the script. In 'Basic' I would have used the frowned upon "goto" script-start; but how do I realize this in my script? There are certainly better ways.
#! /bin/bash
start() {
echo "Welcome to 'my script'"
}
function1() {
code1
}
function2() {
code2
}
critical_funktion() {
if [[ condition... ]]; then
echo " ... "
fi
}
function3() {
code3
}
# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
# main program
start
function1
# evaluation function1
function2
# evaluation function2
critical_funktion
# evaluation critical_funktion
if [ $? -eq 0 ]; then
echo "all right"
else
**goto start ???**
fi
function3
# evaluation function3
exit 0
Yes, there are certainly better ways. I'll show one, I determine better. The method is to put the part that is repeated into a loop.
An example:
while :; do
start
function1
function2
# if critical_function returns zero -> break out of the loop.
# else: repeat the loop
critical_function && break
done
# continue further with the program
function3
exit 0
If the block within the loop is too big, you can move the block into another function and just call that function in the loop.
I guess a 'while-loop construct' is the right way to the solution. Based on joker's idea I've written a mini test-script, which runs exactly as expected, with the following script flow:
#!/bin/bash
start() {
echo "Welcome to 'my script'"
echo ""
}
function1() {
echo "here runs function1"
echo ""
}
function2() {
echo "here runs function2"
echo ""
}
critical_function() {
echo "here runs critical_function"
read -p "Input 2 variables: " var1 var2
if [ "$var1" == "$var2" ]; then
tag=0
echo "critical_function: all right"
else
tag=1
echo "critical_function: input error"
fi
}
function3() {
echo "here runs function3"
}
# continue further with the program function3
# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
# main program
while : ; do
start
function1
function2
# if critical_function returns zero -> break out of the loop.
# else: repeat the loop
critical_function
if [[ "${tag}" -ne 0 ]]; then
continue
fi
break
done
function3
exit 0
Besides using loops instead of goto another basic advice in programming is to avoid global variables whenever possible, because of increased risk of interference of different program parts.
I have another improvement suggestion for your program, keeping the program flow as you introduced it, using the exit code of a function and a local variable with a visibility scope only within a function.
critical_function() {
# declare the variable named "tag" as local
# only accessible within this function
local tag
echo "here runs critical_function"
read -p "Input 2 variables: " var1 var2
if [ "$var1" == "$var2" ]; then
tag=0
echo "critical_function: all right"
else
tag=1
echo "critical_function: input error"
fi
return $tag
}
# main program
while : ; do
start
function1
function2
# if critical_function returns zero -> break out of the loop.
# else: repeat the loop
critical_function && break
done
Ok, all clear. Your explanation was more related to my 1ˢᵗ trial; anyway now I'm focusing on joker's modified script. Thanks again.
btw: My question may be marked as 'solved'.