Bash doesn't have a goto operator. I have a simple task, and I can't figure out how to solve it without goto or adding a new proc, and that is undesireable.
I have two conditions and a block of code that should work this way:
[ condition 1 ] if true run some commands and check [ condidion 2 ]; if false exec a block of code.
[ condition 2 ] if true don't exec the same block of code; if false do execute the same block.
Is it solvable, or I have to define some proc and use exit
there? I used a flag var, but I don't like it.
With goto available it would look this way:
[ cond 1 ] || goto label 1
command
...
command
[ cond 2 ] && goto label 2
:label 1
block of code
:label 2
Something like that.
The typical way to work to use branching in shell scripts would be via functions declared before main block of code. However, I think the underlying issue here is the logical one, and not the goto. Obviously
label 1
is repeated, so this can live as function. But also, condition 2 could be turned into a function that also callslabel 1
for the sake of readability:What I've noticed is that in both conditions you have
if false exec a block of code
andif false exec a block of code
, so one idea would be to start at checking whether those conditions both false. However, making something likeif ! [ cond1 ] || ! [ cond2 ]
would change branching logic. You can still see the pseudocode version of that by seeing this posts edit history.When I moved from Windows to Linux on my desktop, I had a lot of pre-existing
.BAT
and.CMD
files to convert and I wasn't going to rewrite the logic for them, so I found a way to do agoto
in bash that works because thegoto function
runssed
on itself to strip out any parts of the script that shouldn’t run, and then evals it all.The below source is slightly modified from the original to make it more robust:
and I do not feel guilty at all as Linus Torvalds famously said:
Original source for the code (modified to make it less error prone)
The source for the quote
You should put your
block_of_code
into a function and use some if/else: