296

Is there a "goto" statement in Bash?

I know it is considered bad practice, but I need specifically a "goto".

Valerio Bozz
  • 1,176
  • 16
  • 32
kofucii
  • 7,393
  • 12
  • 51
  • 79
  • 6
    No, there's not `goto` in bash (at least it says `command not found` for me). Why? Chances are there is a better way to do it. – Niklas B. Mar 09 '12 at 18:27
  • 4
    You never need goto, at worst you need more practice with other control flow tools. –  Mar 09 '12 at 18:33
  • 196
    He may have his reasons. I found this question because I want a `goto` statement to skip over a lot of code for debugging a large script without waiting an hour for various unrelated tasks to complete. I'd certainly not use a `goto` in the production code, but for debugging my code, it'd make my life infinitely easier, and it'd be easier to spot when it came to remove it. – Karl Nicoll Jul 06 '12 at 10:40
  • 38
    @delnan But having no goto can make some things more complicated. There indeed are use cases. – glglgl May 15 '13 at 13:56
  • It would help if you would specify your reason for needing it. If it is for exception handling, create a function with an exit statement in it and call that function... Also, if you have a large script with lots of debugging statements, if would be much more readable with an if statement or split it up into multiple functions. Its not a good idea to create Bash scripts that are hundreds of lines long without splitting it up into mutiple functions, just like any other programming language. – Justin Rowe Jul 19 '13 at 12:41
  • 2
    @KarlNicoll I also want it for debugging purpose. We won't care best practises while debugging the code. – Mohammed H Jan 02 '14 at 13:01
  • 97
    I'm sick of this goto myth! There's nothing wrong with goto! Everything you write eventually becomes goto. In assembler, there is only goto. A good reason to use goto in higher programming languages is for example jumping out of nested loops in a clean and readable way. – ACz Jul 03 '14 at 15:07
  • 2
    @alexc Sorry, but no - jumping out of nested loops is exactly (one of) the reasons so many people hate goto! There are reasonable use cases for it, but that isn't one of them, and even if it was, it would only be a reason to have multi-level continue statements; not a generalized goto. Still, you're right - and I agree with your conclusion, even if not your example. – Benubird Dec 10 '14 at 21:01
  • 2
    I have the worst reason of all - porting windows cmd files more-or-less 1:1 to bash. They usually have little to zero structuring except on the "goto" level... – Stefan Hegny Sep 27 '16 at 11:53
  • 46
    "Avoid goto" is a great rule. Like any rule, it should be learned in three phases. First: follow the rule until it's second nature. Second, learn to understand the reasons for the rule. Third, learn good exceptions to the rule, based on a comprehensive understanding of how to follow the rule and the reasons for the rule. Avoid skipping steps above, which would be like using "goto". ;-) – Jeff Learman Jun 30 '17 at 23:44
  • 1
    The shell used to have a `goto` command. The `:` command which used to make a label is a rudiment of this. However, no such feature remains today. – fuz Dec 11 '17 at 14:34
  • 1
    I think we've discovered the problem. GOTO has been omitted from the shell. Who can we get to fix this oversight? – Engineer Mar 18 '19 at 23:34
  • C shell has a goto: https://linux.die.net/man/1/csh – Roland Apr 17 '20 at 07:01
  • goto is 'considered harmful' but if you do use it do not have multiple ones which cross the lines of other gogo commands. i.e. don't have a gogo which jumps from line 1 to 5 and then another one that jumps to 3. This causes nightmare spaghetti. Also, only jumping forward is another good giudeline. – Ben Edwards Apr 19 '20 at 13:09
  • @StefanHegny That's presumably because of how eager `%expansion%` is in the DOS/Windows command.com/cmd.exe language; read all about it in [`help set`](https://gist.github.com/SamB/957ae854d2f58d79e03da25d8a42bf22). – SamB Jan 30 '21 at 19:26
  • Bash is a scripting language, and (along with other shell langs) the only language that literally everyone uses it more on a REPL than in files. This makes code style rules in Bash fundamentally different from all other (non-shell) langs. For example, goto is usually an antipattern in other languages because it leads to inconsistent states, but in Bash, you often come to a case where there're overwhelmingly more stateless lines than stateful (variable-assigning) lines. On the other hand, filesystem-manipulating lines are stateful in another manner, which happens regardless whether goto is used – SOFe May 13 '22 at 03:22
  • The main difference is that Bash is (usually) used by a human, just to execute a bunch of commands quickly without typing so much. Nobody runs an unattended server in Bash. This means if there are any unexpected states, the human should be able to repair it immediately; in particular, scripts are usually just used by the person who wrote the script, which means he knows how to debug it. Especially with `set -x` turned on. Also, error recovery is quite handy when there is `set -e`. – SOFe May 13 '22 at 03:25
  • @MikeSchinkel how do you define "runs in an unattended server"? it is very normal to have a Bash script that acts as an entrypoint to a server image, even a complex one, which is *usually* fine as long as it works and it is able to start the main process. Or do you mean your Bash script is actually part of the main loop, such that it runs even after the server started and so bugs in the Bash script could lead to divergent server behavior that cannot be immediately spotted without careful testing (in contrast to running it once)? – SOFe Oct 30 '22 at 12:32
  • that said, I think it is pretty obvious that you shouldn't use `goto` in an unattended script (as much as you shouldn't use `goto` in a C program that needs to be maintained for more than a few hours). And `goto` is arguably much less harmful than lack of `set -euo pipefail` by default. – SOFe Oct 30 '22 at 12:35
  • @SOFe — All of the above. People develop and run complete server applications in Bash. Now I am _**not endorsing**_ the development of server apps in Bash, but believing that no one done does is naive, and asserting to people on a site like this that they don't — when it is impossible for you to know they don't — is irresponsible. Which is why I commented. – MikeSchinkel Nov 01 '22 at 01:06
  • 1
    @SOFe — I will also challenge your assertions regarding `goto` — there is nothing about responsible use of `goto` that is problematic. Thinking otherwise is evidence of uncritically accepting conventional wisdom arising from the regrettably-named anti-`goto` essay that, according to its author _(verbatim quote here_): _"in later years would be most frequently referenced, regrettably, however, often by authors who had seen no more of it than its title."_. No, server apps can be _**more robust and diagnosable**_ when `goto` is used: https://github.com/mikeschinkel/goto-considered-beneficial – MikeSchinkel Nov 01 '22 at 01:16

14 Answers14

174

No. But, if you are using it to skip part of a large script for debugging (see Karl Nicoll's comment), then if false could be a good workaround.

# ... Code I want to run here ...

if false; then

# ... Code I want to skip here ...

fi

# ... I want to resume here ...

The difficulty comes in when it's time to rip out your debugging code. The "if false" construct is pretty straightforward and memorable, but how do you find the matching fi? If your editor allows you to block indent, you could indent the skipped block (then you'll want to put it back when you're done). Or a comment on the fi line, but it would have to be something you'll remember, which I suspect will be very programmer-dependent.

Valerio Bozz
  • 1,176
  • 16
  • 32
Michael Rusch
  • 2,479
  • 2
  • 16
  • 20
  • 8
    Yes `false` is always available. But if you have a block of code you don't want to execute, just comment it out. Or delete it (and look in your source control system if you need to recover it later). – Keith Thompson Nov 17 '13 at 15:21
  • 1
    If ithe block of code is too long to tediously comment out one line at a time, see these tricks. http://stackoverflow.com/questions/947897/block-comments-in-a-shell-script However, these don't help a text editor match the beginning to the end, either, so they're not much of an improvement. – Camille Goudeseune Jun 21 '16 at 15:48
  • 4
    "if false" is often far better than commenting out code, because it ensures that the enclosed code continues to be legal code. The best excuse for commenting out code is when it really needs to be deleted, but there's something that needs to be remembered -- so it's just a comment, and no longer "code". – Jeff Learman Jun 30 '17 at 23:46
  • 3
    I use the comment '#if false;'. That way I can just search for that and find both the beginning and end of the debug removal section. – Jon Nov 08 '18 at 20:32
  • 2
    This answer should not be upvoted since it doesn't respond to the OP's question in any way. – Viktor Joras Apr 19 '19 at 12:13
  • Ripping out that `if false` bit is as easy as changing it to `if true`. Not as clean as properly removing it, of course, but it's simple enough. – Sinus the Tentacular Sep 04 '20 at 17:08
  • 1
    "not sure if "false" is always available, for me it is in /bin/false" bash has its own `false` command that does not trigger the OS /bin/false. So since OP is referring to Bash, `false` is always available even in those "distroless" docker images that do not have /bin/false. – SOFe Oct 30 '22 at 12:38
103

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 . . .)

ruakh
  • 175,680
  • 26
  • 273
  • 307
  • 17
    Could you expand on "more flexible in Bash than in some languages"? – user239558 Apr 28 '14 at 09:00
  • 28
    @user239558: Some languages only allow you to `break` or `continue` from the innermost loop, whereas Bash lets you specify how many levels of loop to jump. (And even of languages that allow you to `break` or `continue` from arbitrary loops, most require that to be expressed statically -- e.g., `break foo;` will break out of the loop labeled `foo` -- whereas in Bash it's expressed dynamically -- e.g., `break "$foo"` will break out of `$foo` loops.) – ruakh Apr 28 '14 at 16:37
  • 1
    I'd recommend defining functions with the needed features and caling them from other parts of the code. – blmayer Jun 21 '19 at 23:23
  • @ruakh Actually, many languages allow `break LABEL_NAME;`, rather than Bash's disgusting `break INTEGER;`. – Sapphire_Brick Jun 29 '20 at 18:37
  • 2
    @Sapphire_Brick: Yes, I mentioned that in the comment that you're replying to. – ruakh Jun 29 '20 at 18:44
  • 1
    @ruakh _Oh._. My bad. – Sapphire_Brick Jun 29 '20 at 19:06
81

It indeed may be useful for some debug or demonstration needs.

I found that Bob Copeland solution http://bobcopeland.com/blog/2012/10/goto-in-bash/ elegant:

#!/bin/bash
# include this boilerplate
function jumpto
{
    label=$1
    cmd=$(sed -n "/$label:/{:a;n;p;ba};" $0 | grep -v ':$')
    eval "$cmd"
    exit
}

start=${1:-"start"}

jumpto $start

start:
# your script goes here...
x=100
jumpto foo

mid:
x=101
echo "This is not printed!"

foo:
x=${x:-10}
echo x is $x

results in:

$ ./test.sh
x is 100
$ ./test.sh foo
x is 10
$ ./test.sh mid
This is not printed!
x is 101
Hubbitus
  • 5,161
  • 3
  • 41
  • 47
  • 58
    "My quest to make bash look like assembly language draws ever nearer to completion." - Wow. Just, wow. – Brian Agnew Mar 08 '16 at 16:00
  • 5
    the only thing I'd change is make it so that labels start like so `: start:` so that they aren't syntax errors. – Alexej Magura Apr 07 '17 at 18:03
  • 1
    I love this. Suddenly debugging got way faster. – C0ppert0p Apr 18 '17 at 23:01
  • 6
    Would be better if you did that: cmd=$(sed -n "/#$label:/{:a;n;p;ba};" $0 | grep -v ':$') with labels starting as: #start: => this would prevent script errors – access_granted Apr 19 '17 at 22:30
  • I'm getting segmentation faults. Going to try the suggestions where labels are commented out. Update: I think it's trying execute the labels and crashing. Starting the label with a ": " or # as suggested seemed to fix that. Great work, can't wait to try this out. – thebunnyrules Mar 24 '18 at 06:53
  • 1
    Actually this script is written by Robert Copeland not Judy. – Cloud Cho Apr 20 '18 at 01:47
  • @CloudCho I refer to Judy blogpost... Where you find other copyright? I should edit post to reflect this if it true. – Hubbitus Apr 22 '18 at 23:55
  • @Hubbitus ... I went the link (http://bobcopeland.com...) you posted. Isn't the link belonging to Bob Coperland? I thought Judy just made a comment on his website. Please, let me know if I misunderstood. – Cloud Cho Apr 23 '18 at 15:41
  • 2
    Hm, indeed it most likely my mistake. I have edit post. Thank you. – Hubbitus Apr 23 '18 at 16:46
  • 3
    `set -x` helps understand what's going on – John Lin Aug 22 '18 at 01:30
  • 1
    **Issues**: 1) Indiscriminately removes all lines ending in a `:`. 2) Treats `label:` anywhere on a line as a label. See [here](https://stackoverflow.com/a/52872489/5353461) for the resolution. – Tom Hale Oct 18 '18 at 11:03
  • @AlexejMagura there is [potential for those errors to be useful](https://stackoverflow.com/questions/8886065/bash-script-error-catching) and/or mitigated if desired – That Realty Programmer Guy Sep 28 '19 at 00:56
  • Could you please add an explanation of how this works as well? – Johan Walles Dec 02 '20 at 11:38
  • @JohanWalles all is pretty simple. Sed manipulate by script-file run from ($0 variable) and extract desired part, then evaluates it and exits – Hubbitus Dec 03 '20 at 16:15
  • In bash, there's always a way. – André Chalella Apr 12 '23 at 11:44
  • It works for me in GNU sed version but not in macOS sed version. A error message: sed: 1: "/:start:/{:a;n;p;ba};": unexpected EOF (pending }'s) – Sangcheol Choi May 12 '23 at 01:15
  • Sorry, unfortunately, I have no MacOS now to check. – Hubbitus May 12 '23 at 16:29
36

If you're testing/debugging a bash script, and simply want to skip forwards past one or more sections of code, here is a very simple way to do it that is also very easy to find and remove later (unlike most of the methods described above).

#!/bin/bash

echo "Run this"

cat >/dev/null <<GOTO_1

echo "Don't run this"

GOTO_1

echo "Also run this"

cat >/dev/null <<GOTO_2

echo "Don't run this either"

GOTO_2

echo "Yet more code I want to run"

To put your script back to normal, just delete any lines with GOTO.

We can also prettify this solution, by adding a goto command as an alias:

#!/bin/bash

shopt -s expand_aliases
alias goto="cat >/dev/null <<"

goto GOTO_1

echo "Don't run this"

GOTO_1

echo "Run this"

goto GOTO_2

echo "Don't run this either"

GOTO_2

echo "All done"

Aliases don't usually work in bash scripts, so we need the shopt command to fix that.

If you want to be able to enable/disable your goto's, we need a little bit more:

#!/bin/bash

shopt -s expand_aliases
if [ -n "$DEBUG" ] ; then
  alias goto="cat >/dev/null <<"
else
  alias goto=":"
fi

goto '#GOTO_1'

echo "Don't run this"

#GOTO1

echo "Run this"

goto '#GOTO_2'

echo "Don't run this either"

#GOTO_2

echo "All done"

Then you can do export DEBUG=TRUE before running the script.

The labels are comments, so won't cause syntax errors if disable our goto's (by setting goto to the ':' no-op), but this means we need to quote them in our goto statements.

Whenever using any kind of goto solution, you need to be careful that the code you're jumping past doesn't set any variables that you rely on later - you may need to move those definitions to the top of your script, or just above one of your goto statements.

  • 3
    Without getting into the good/bad-ness of goto's, Laurence's solution is just cool. You got my vote. – Mogens TrasherDK Dec 04 '17 at 04:27
  • 1
    That's more like a skip-to, an `if(false)` seems to make more sense (to me). – vesperto Feb 23 '18 at 08:56
  • 2
    Quoting the goto "label" also means that the here-doc *is not* expanded/evaluated which saves you from some hard to find bugs (unquoted, it would be subject to: parameter expansion, command substitution, and arithmetic expansion, which can all have side-effects). You can also tweak this a little with `alias goto=":<<"` and dispense with `cat` altogether. – mr.spuratic Jan 04 '19 at 11:48
  • 1
    yes, vesperto, you can use an 'if' statement, and I've done that in many scripts, but it gets very messy and is much harder to control and keep track of, especially if you want to change your jump points frequently. – Laurence Renshaw Jan 07 '19 at 15:50
  • 1
    This is very interesting. You could improve the answer by explaining *why* this works, why the `cat <<` command does the trick. – ysap Apr 04 '21 at 15:33
  • @ysap It's not `cat <<`, it's [Bash's](https://www.gnu.org/software/bash/manual/bash.html#Here-Documents) [_heredoc_](https://en.wikipedia.org/wiki/Here_document): `[n]<<[-]word`\n`here-document`\n`delimiter` the contents of which are `stdin` to `cat` which prints it to `/dev/null`. – Gerold Broser Dec 06 '21 at 21:00
35

You can use case in bash to simulate a goto:

#!/bin/bash

case bar in
  foo)
    echo foo
    ;&

  bar)
    echo bar
    ;&

  *)
    echo star
    ;;
esac

produces:

bar
star
Paul Brannan
  • 1,625
  • 20
  • 20
  • 4
    Note that this requires `bash v4.0+`. It is, however, not a general-purpose `goto` but a fall-through option for the `case` statement. – mklement0 Apr 15 '14 at 18:20
  • 5
    i think this should be the answer. i have a genuine need for go to in order to support resume execution of a script, from a given instruction. this is, in every way but semantic, goto, and semantics and syntactic sugars are cute, but not strictly necessary. great solution, IMO. – nathan g Mar 23 '15 at 14:32
  • 1
    @nathang, whether it's **the** answer depends on whether your case happens to mesh with the subset of the general case the OP asked about. Unfortunately, the question asks about the general case, making this answer too narrow to be correct. (Whether that question should be _closed_ as too broad for that reason is a different discussion). – Charles Duffy Aug 12 '15 at 20:00
  • 1
    goto is more than selecting. goto feature means to be able to jump to places acording to some conditions, creating even a loop like flow... – Sergio Abreu Jan 02 '17 at 22:29
17

Although others have already clarified that there is no direct goto equivalent in bash (and provided the closest alternatives such as functions, loops, and break), I would like to illustrate how using a loop plus break can simulate a specific type of goto statement.

The situation where I find this the most useful is when I need to return to the beginning of a section of code if certain conditions are not met. In the example below, the while loop will run forever until ping stops dropping packets to a test IP.

#!/bin/bash

TestIP="8.8.8.8"

# Loop forever (until break is issued)
while true; do

    # Do a simple test for Internet connectivity
    PacketLoss=$(ping "$TestIP" -c 2 | grep -Eo "[0-9]+% packet loss" | grep -Eo "^[0-9]")

    # Exit the loop if ping is no longer dropping packets
    if [ "$PacketLoss" == 0 ]; then
        echo "Connection restored"
        break
    else
        echo "No connectivity"
    fi
done
Seth McCauley
  • 983
  • 11
  • 24
11

This solution had the following issues:

  • Indiscriminately removes all code lines ending in a :
  • Treats label: anywhere on a line as a label

Here's a fixed (shell-check clean and POSIX compatible) version:


#!/bin/sh

# GOTO for bash, based upon https://stackoverflow.com/a/31269848/5353461
goto() {
  label=$1
  cmd=$(sed -En "/^[[:space:]]*#[[:space:]]*$label:[[:space:]]*#/{:a;n;p;ba};" "$0")
  eval "$cmd"
  exit
}

start=${1:-start}
goto "$start"  # GOTO start: by default

#start:#  Comments can occur after labels
echo start
goto end

  # skip: #  Whitespace is allowed
echo this is usually skipped

# end: #
echo end
greybeard
  • 2,249
  • 8
  • 30
  • 66
Tom Hale
  • 40,825
  • 36
  • 187
  • 242
6

There is one more ability to achieve a desired results: command trap. It can be used to clean-up purposes for example.

Serge Roussak
  • 1,731
  • 1
  • 14
  • 28
6

There is no goto in bash.

Here is some dirty workaround using trap which jumps only backwards:)

#!/bin/bash -e
trap '
echo I am
sleep 1
echo here now.
' EXIT

echo foo
goto trap 2> /dev/null
echo bar

Output:

$ ./test.sh 
foo
I am
here now.

This shouldn't be used in that way, but only for educational purposes. Here is why this works:

trap is using exception handling to achieve the change in code flow. In this case the trap is catching anything that causes the script to EXIT. The command goto doesn't exist, and hence throws an error, which would ordinarily exit the script. This error is being caught with trap, and the 2>/dev/null hides the error message that would ordinarily be displayed.

This implementation of goto is obviously not reliable, since any non-existent command (or any other error, for that manner), would execute the same trap command. In particular, you cannot choose which label to go-to.


Basically in real scenario you don't need any goto statements, they're redundant as random calls to different places only make your code difficult to understand.

If your code is invoked many times, then consider to use loop and changing its workflow to use continue and break.

If your code repeats it-self, consider writing the function and calling it as many times as you want.

If your code needs to jump into specific section based on the variable value, then consider using case statement.

If you can separate your long code into smaller pieces, consider moving it into separate files and call them from the parent script.

Alex
  • 947
  • 1
  • 8
  • 25
kenorb
  • 155,785
  • 88
  • 678
  • 743
  • what's the differences between this form and a normal function? – yurenchen Jun 01 '16 at 02:39
  • 2
    @yurenchen - Think of `trap` as using `exception handling` to achieve the change in code flow. In this case the trap is catching anything that causes the script to `EXIT`, which is triggered by invoking the non-existent command `goto`. BTW: The argument `goto trap` could be anything, `goto ignored` because it is the `goto` that causes the EXIT, and the `2>/dev/null` hides the error message saying your script is exiting. – Jesse Chisholm Dec 05 '16 at 19:28
  • I am having following error: `permission denied: /dev/nul` – alper Aug 10 '21 at 17:43
3

I found out a way to do this using functions.

Say, for example, you have 3 choices: A, B, and C. A and Bexecute a command, but C gives you more info and takes you to the original prompt again. This can be done using functions.

Note that since the line containg function demoFunction is just setting up the function, you need to call demoFunction after that script so the function will actually run.

You can easily adapt this by writing multiple other functions and calling them if you need to "GOTO" another place in your shell script.

function demoFunction {
        read -n1 -p "Pick a letter to run a command [A, B, or C for more info] " runCommand

        case $runCommand in
            a|A) printf "\n\tpwd being executed...\n" && pwd;;
            b|B) printf "\n\tls being executed...\n" && ls;;
            c|C) printf "\n\toption A runs pwd, option B runs ls\n" && demoFunction;;
        esac
}

demoFunction
cutrightjm
  • 657
  • 2
  • 6
  • 20
3

This is a small correction of the Judy Schmidt script put up by Hubbbitus.

Putting non-escaped labels in the script was problematic on the machine and caused it to crash. This was easy enough to resolve by adding # to escape the labels. Thanks to Alexej Magura and access_granted for their suggestions.

#!/bin/bash
# include this boilerplate
function goto {  
label=$1
cmd=$(sed -n "/$#label#:/{:a;n;p;ba};" $0 | grep -v ':$')
eval "$cmd"
exit
}

start=${1:-"start"}

goto $start

#start#
echo "start"
goto bing

#boom#
echo boom
goto eof

#bang#
echo bang
goto boom

#bing#
echo bing
goto bang

#eof#
echo "the end mother-hugger..."
Fabby
  • 315
  • 4
  • 14
thebunnyrules
  • 1,520
  • 15
  • 22
  • This copy paste is not working => there is still a jumpto. – Alexis Paques Aug 03 '18 at 11:18
  • What does that mean? What's not working? Could you be more specific? – thebunnyrules Aug 05 '18 at 16:26
  • Of course I tried the code! I tested under 5 or 6 different conditions before posting all successful. How did the code fail for you, what error message or code? – thebunnyrules Aug 11 '18 at 03:50
  • Whatever man. I want to help you but you're being really vague and uncommunicative (not to mention insulting with that "did you test it" question). What does "you didn't paste correctly mean"? If you're referring to the "/$#label#:/{:a;n;p;ba};" part, I'm very aware that it's different. I modified it for the new label format (aka #label# vs :label in other answer which was crashing script in some cases). Do you have some valid problem with my answer (like script crash or bad syntax) or did you simply -1 my answer because you thought "I don't know how to cut and paste"? – thebunnyrules Aug 13 '18 at 01:18
  • `jumpto $start` – Alexis Paques Aug 15 '18 at 09:01
  • The reason is that it does not add much added values to the precedent answers and it is not working as intended because the function name has been changed in between. – Alexis Paques Aug 15 '18 at 09:02
  • 1
    @thebunnyrules I ran into the same issue as you but [solved it differently](https://superuser.com/a/1353588/398314) **+1 for your solution though!** – Fabby Aug 30 '18 at 18:22
  • @Alex Paques the main answer was crashing because bash didn't know what to do with tags that begin with : :tag1 :tag2 etc. Adding a # instead of : fixed that. Sorry if you don't think fixing a big bug like this adds anything. And "a non sarcastic" sorry about it crashing on your PC. I did test it quite a bit before posting it but these things are hard to completely test for sometime. – thebunnyrules Sep 01 '18 at 02:55
  • @AlexisPaques and I changed the incorrect statement you were referring to. =time to remove the downvote? **;-)** Next time just edit as it's very hard for yourself to see a dumb copy-paste error. Also notified the original author of my solution to the issue. – Fabby Sep 02 '18 at 10:07
2

A simple searchable goto for the use of commenting out code blocks when debugging.

GOTO=false
if ${GOTO}; then
    echo "GOTO failed"
    ...
fi # End of GOTO
echo "GOTO done"

Result is-> GOTO done

ztalbot
  • 119
  • 1
  • 4
0

My idea for creating something like "goto" is to use select with case and assign a variable, which I then check in an if statement. Not perfect, but may help in some cases

Example:

#!/usr/bin/env bash

select goto in Ubuntu Debian Quit ; do
    case $goto in
        Ubuntu) { CHOICE="Ubuntu" ; break ; } ;;
        Debian) { CHOICE="Debian" ; break ; } ;;
        Quit)   { echo "Bye" ; exit ; } ;;
        *)      { echo "Invalid selection, please try again..." ; } ;;
    esac
done

if [ "$CHOICE" == "Ubuntu" ]; then
    echo "I'm in Ubuntu"
fi

if [ "$CHOICE" == "Debian" ]; then
    echo "I'm in Debian"
fi

kanlukasz
  • 1,103
  • 19
  • 34
0

Why don't anyone just use functions directly ?
BTW functions are easier to deal with than making a new thing

My style :

#!/bin/bash

# Your functions
function1 ()
{
    commands
}

function2 ()
{
    commands
}
    :
    :

functionn ()
{
    commands
}

# Execute 1 to n in order
for i in {1..n}
    do
        function$i
    done

# with conditions
for i in {1..n}
    do
        [ condition$i ] && function$i
    done

# Random order
function1
functionn
function5
    :
    :
function3

Example for above style :

#!/bin/bash

# Your functions
function1 ()
{
    echo "Task 1"
}

function2 ()
{
    echo "Task 2"
}

function3 ()
{
    echo "Task 3"
}

function1
function3
function2

Output :

Task 1
Task 3
Task 2

Drawbacks :

  • Script in an organized way.
  • Less problems and not prone to errors.
  • You can make function inside a existing function.
  • Move back and forth without any problems.
Hackdev17
  • 29
  • 5
  • "Why don't anyone just use functions directly ?" If you need to step through and debug an existing script to break it out into functions because it wasn't in the first place :) . – JohnZaj Dec 02 '22 at 18:25