Is There a "Goto" Statement in Bash

Is there a goto statement in bash?

No, there is not; see §3.2.4 "Compound Commands" in the Bash Reference Manual for information about the control structures that do exist. In particular, note the mention of break and continue, which aren't as flexible as goto, but are more flexible in Bash than in some languages, and may help you achieve what you want. (Whatever it is that you want . . .)

How to use goto statement in shell script

As others have noted, there's no goto in bash (or other POSIX-like shells) - other, more flexible flow-control constructs take its place.

Look for heading Compound Commands in man bash.

In your case, the select command is the right choice.
Since how to use it may not be obvious, here's something to get you started:

#!/usr/bin/env bash

echo "Main Menu"

# Define the choices to present to the user, which will be
# presented line by line, prefixed by a sequential number
# (E.g., '1) copy', ...)
choices=( 'copy' 'exit' )

# Present the choices.
# The user chooses by entering the *number* before the desired choice.
select choice in "${choices[@]}"; do

# If an invalid number was chosen, $choice will be empty.
# Report an error and prompt again.
[[ -n $choice ]] || { echo "Invalid choice." >&2; continue; }

# Examine the choice.
# Note that it is the choice string itself, not its number
# that is reported in $choice.
case $choice in
copy)
echo "Copying..."
# Set flag here, or call function, ...
;;
exit)
echo "Exiting. "
exit 0
esac

# Getting here means that a valid choice was made,
# so break out of the select statement and continue below,
# if desired.
# Note that without an explicit break (or exit) statement,
# bash will continue to prompt.
break

done

Skip (goto) a piece of code in bash?

No, there isn't.

But this example doesn't need it:

read -p "WAN1 exists?: " -n 1 -r
if [[ $REPLY =~ ^[Yy]$ ]]; then
# WAN1
read -p "Enter WAN1 IP: " wan1
if [[ $wan1 =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then
sed -i~ -e "s/bizip/$wan1/g" test.txt
else
echo Error
fi
fi
# WAN2_prompt
read -p "WAN2 exists?: " -n 1 -r
if [[ $REPLY =~ ^[Yy]$ ]]; then
read -p "Enter WAN2 IP: " wan2
if [[ $wan2 =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then
sed -i~ -e "s/bizip/$wan2/g" test.txt
else
echo Error
fi
fi
# ...

Goto beginning of if statement?

You have to use a loop; bash doesn't have a goto statement.

while true; do
# set the value of INPUT here
if [ "$INPUT" = "no" ]; then
Do something
elif [ "$INPUT" = "yes" ]; then
Do something else
else
echo "Input not understood"
continue
fi
break
done

In this "infinite" loop, we use the continue statement in the else clause to return to the top of the loop, where we do something to get a new value of INPUT. If we don't execute the else clause, we hit the break statement, which exits the loop.

how do you goto in mac shell (like a in windows .bat)?

There's actually no exact replacement. In bash programming, you can define functions, so you might do something like

one() {
# Some stuff
two
}

two() {
# Some more stuff
one
}

Although eventually that'll run out of stack space; hopefully there's some circumstances under which you'll include code to stop the recursion. I realize this is just a straw man example, but bash would let you use other forms of loops here which would work better; for example:

while true
do
# Some stuff
# Some more stuff
done

What could be the substitute to handle the flow control of go-to in SHELL script

Rather than trying to extend the syntax of the shell to do

start:

for ...; do
for ...; do
...
done
done

if CONDITION; then
goto start
else
SOMETHING
fi

you may do

while true; do
for ...; do
for ...; do
...
done
done

if ! CONDITION; then
SOMETHING
break
fi
done

or

while true; do
for ...; do
for ...; do
...
done
done

if ! CONDITION; then
break
fi
done

SOMETHING

UPDATE: New code in question:

start:
while true; do
for ...; do
for ...; do
if ...; then
break 99
fi
...
done
done
done

...

if CONDITION; then
SOMETHING
goto start
else
SOMETHING_ELSE
fi

for ...; do
...
done

To avoid a goto, this may be transformed into

while true; do
while true; do
for ...; do
for ...; do
if ...; then
break 99 # change to one less than
# the total depth, to not exit
# outermost loop
fi
...
done
done
done

...

if ! CONDITION; then
break
fi

SOMETHING
done

SOMETHING_ELSE

for ...; do
...
done

Something similar to goto on linux

Bourne shells like sh and bash don't have GOTO statements. It's considered harmful.

Instead, use structured flow control like if statements:

echo "Enter the number to divide (dividend) (enter 999 to quit):"
read numberOne
if [ "$numberOne" -ne 999 ]
then
echo "Enter the number to divide (divisor) (enter 999 to quit):"
read numberTwo

while [ "$numberOne" -ne '999' ] && [ "$numberTwo" -ne '999' ]
do
while [ "$numberTwo" -eq 0 ]
do
echo "You cannot divide by 0, please enter another number:"
read numberTwo
done

RESULT=$(echo "$numberOne/$numberTwo" | bc -l)
echo $numberOne / $numberTwo = $RESULT
echo $numberOne / $numberTwo = $RESULT >> results.txt
echo "Enter the number to divide (dividend) (enter 999 to quit):"
read numberOne
if [ "$numberOne" -ne 999 ]
then
echo "Enter the number to divide (divisor) (enter 999 to quit):"
read numberTwo
fi
done
fi

counter=1
totalCount=0
temporal=0

while [ "$counter" -lt '101' ]
do
temporal=$( expr $counter % 5)
echo $counter MOD 5 = $temporal
echo $counter MOD 5 = $temporal >> results.txt
totalCount=$(echo "$totalCount+$temporal" | bc -l)
counter=$(echo "$counter+1" | bc -l)
done

average=$(echo "$totalCount/100" | bc -l)
echo The average of all the MODs is $average >> results.txt

It may seem more awkward than one simple goto, but as you take advantage of more structured control flow, the code gets easier to read and follow:

readNumber() {
local number
read -p "$1" number
[ "$number" -ne 999 ] && echo "$number"
}

while one=$(readNumber "Enter dividend or 999 to quit: ") && \
two=$(readNumber "Enter divisor or 999 to quit: ")
do
echo "$one / $two = $(echo "$one / $two" | bc -l)" | tee results.txt
done

This keeps asking for numbers to divide, until the user enters 999 for either of them.



Related Topics



Leave a reply



Submit