[HN Gopher] Goto in Bash (2012)
       ___________________________________________________________________
        
       Goto in Bash (2012)
        
       Author : davidcollantes
       Score  : 58 points
       Date   : 2023-08-03 11:53 UTC (11 hours ago)
        
 (HTM) web link (bobcopeland.com)
 (TXT) w3m dump (bobcopeland.com)
        
       | knome wrote:
       | the author mentions in a note that bash was complaining and that
       | they might put the labels in comments to dodge the issue. They
       | might also be able to change the label format to `: label`. `:`
       | just returns true regardless of what parameters you pass it, so
       | it could still look "labelish" without having to use an actual
       | comment.
        
       | alganet wrote:
       | This is silly. Whatever can be done with this approach can be
       | better written with just functions.
        
       | t0astbread wrote:
       | That's neat but doesn't `case` support fallthrough? So I expect
       | you could just put your script in one big `case` statement and
       | skip to the branch you need.
        
       | taviso wrote:
       | It's a funny trick, but you could probably also use setjmp and
       | longjmp with ctypes.sh :-)
       | 
       | https://github.com/taviso/ctypes.sh
        
         | tetromino_ wrote:
         | Great heavens! I assumed at first that your "dlopen" was a
         | separate executable, but you are implying you allow calling
         | arbitrary C functions _within the memory space of the bash
         | process itself!?_
        
           | taviso wrote:
           | Yes, exactly... :)
           | 
           | You can also create callbacks (i.e. function pointers to bash
           | code) that you can pass to qsort() or bsearch()... or
           | pthread_create? That last one was a joke, I mean, you
           | probably could but I don't know what would happen - I don't
           | think bash is reentrant :)
        
             | lanstin wrote:
             | Wow, I thought the original article was awful tho good,
             | then I saw the lseek goto which seems much worse, then I
             | see this dlopen for bash and I find it's the worse. But
             | impossibly cool.
             | 
             | Did you have a usecase for this or it was just fun?
        
       | mikepurvis wrote:
       | Since he mentions this being for a work thing, how I've handled a
       | similar situation (long running shell thingies) is:
       | 
       | Break up the script into steps, and place them in order in a
       | dot-d style folder, like 1.foo.sh, 2.bar.sh, 3.baz.sh. Have a
       | separate _context.sh which supplies the upfront variables or
       | whatever are needed for each step. Ensure that each step can run
       | on its own with just the context sourced. Then have a run.sh in
       | the folder above that sources the context and the steps in order.
       | 
       | Now, that said, typically these kinds of things are dataflow or
       | even buildsystem-adjacent, so I've also experimented with doing
       | them in CMake (intermediate products managed with
       | add_custom_target) or as Nix derivations (intermediate products
       | are input-addressed in the Nix store), but I'd love to be aware
       | of other tools that are better for expressing this kind of thing.
        
         | nomel wrote:
         | What's the motivation of this complexity over, say, a more
         | modern programing language that can handle cases like this with
         | ease?
        
         | Joker_vD wrote:
         | I'd write run.sh like this: Put the names of the files from
         | that dot-d style folder into some ".cc" file (if it doesn't
         | exist yet); then loop over the lines in the ".cc" file,
         | executing each line if it doesn't start with '#' and then
         | prepending '#' with sed to the just executed line. After the
         | loop, delete the ".cc" file (maybe with a diagnostic messages
         | if all lines in it were #-prefixed). Maybe throw in some traps
         | for reliable SIGINT-handling as well.
        
       | cramjabsyn wrote:
       | what have you done...
        
       | Borborygymus wrote:
       | And I did cringe, and then I thought it looked kinda fun. It
       | would literally never have occurred to me in a million years to
       | try to start a shell script half way though - so trapped am I in
       | the paradigm of the familiar.
       | 
       | As for the script that takes several days and often breaks half
       | way through... sounds like what Makefiles are for to me.
        
       | js2 wrote:
       | > It runs sed on itself to strip out any parts of the script that
       | shouldn't run, and then evals it all.
       | 
       | How I have done this is:
       | 
       | 1. Put all the steps in functions.
       | 
       | 2. Have a main function that calls all the other functions in
       | order.
       | 
       | 3. If given an argument, the main function skips all the
       | functions up to that one.
        
         | tetris11 wrote:
         | Or just use make, and rerun the command on failure once
         | clearing the error to continue where you left off.
         | 
         | Make is one of the most versatile pipeline tools out there.
        
           | js2 wrote:
           | Yup I've done that too which also gives you free
           | parallelization and as a bonus if the rules don't have a
           | natural product you can always touch a sentinel file in each
           | rule so that make can just pick up where it left off.
           | 
           | TIMTOWTDI.
        
       | ggeorgovassilis wrote:
       | He writes "prepare to cringe" and he is not wrong. As far as I
       | understand, this technique implements GOTO by reading the source
       | code (again) into memory, filtering out everything before the
       | target label and evaluating the remaining source code. I think
       | this doesn't preserve state, variables etc. so not really a GOTO.
       | But interesting technique.
       | 
       | edited for clarity
        
         | throwanem wrote:
         | > I think this doesn't preserve state, variables etc.
         | 
         | Why wouldn't it? It's calling eval, not exec.
        
         | DannyBee wrote:
         | The more frightening part (at least for me) is the reddit
         | thread that points out this is how windows batch files
         | implement goto, and shows how to see it happen.
        
           | throwanem wrote:
           | If that's the scariest thing you know about Windows batch
           | files, you've lived a blameless life.
        
           | KnobbleMcKnees wrote:
           | Does that mean using jumpto to jump to a label above that
           | invocation results in redeclaration of the same code?
           | 
           | Seems janky even by the low standards of the author.
        
       | arthur2e5 wrote:
       | This reminds me of the Thompson shell goto, which is an
       | external(!) program that messes with its parent's file
       | descriptors looking for `: label`.
       | 
       | See manpage at https://etsh.nl/man/_goto.1.html and source code
       | at https://github.com/eunuchs/tsh/blob/master/goto.c.
       | 
       | See, history can give you a more inert syntax. And maybe a new
       | way of thinking about how to make this thing... I would love to
       | have a more robust version to do C-style goto cleanups.
        
         | casey2 wrote:
         | :(1) was also an external program at least in v2 unix
        
       | ufo wrote:
       | Does this also works inside if and while blocks?
        
       | ectospheno wrote:
       | Make first argument your step/label. Each step can have its own
       | command line. Exec yourself. Accomplishes same thing without
       | being scary.
        
       | tragomaskhalos wrote:
       | BAT files writing other BAT files was often the only way to get
       | scripting workflows done on primordial Windows versions, but
       | chaos typically ensued if you attempted to rewrite the file you
       | were presently running, as it appears that cmd didn't do anything
       | fancy like read the whole file into memory before processing it
       | (presumably due to the draconian memory limits people laboured
       | under back then)
        
         | rascul wrote:
         | This is going off of memory as I'm not at my computer. Bash
         | does something similar. It will read and execute the script
         | line by line so if it's modified before bash gets to that line
         | then weird things can happen. However, functions need to be
         | read completely so the trick is to create a main function and
         | call it at the end of the script.
        
       | Joker_vD wrote:
       | That's one of the few places where it would be appropriate to
       | store the current execution point somewhere in /var/cache or
       | /var/lock and write the script so that it would look there at
       | launch and dispatch accordingly.
        
       | vidarh wrote:
       | If you're going to do that, you might as well go the whole hog
       | and implement INTERCAL's "come from"[1] for maximal evil.
       | 
       | [1] https://en.wikipedia.org/wiki/COMEFROM
        
         | Joker_vD wrote:
         | Oh, but we have that construct in our modern high-level
         | languages already, it's just customarily been called "catch
         | block" instead.
        
           | vidarh wrote:
           | Hah! But COME FROM is more insidious - no amount of following
           | the chain of calls will reveal that something is lurking
           | elsewhere in the program ready to redirect the control flow
        
       | otikik wrote:
       | Some men just want to watch the world burn.
        
       | 1equalsequals1 wrote:
       | Thanks I hate it
        
       | 8chanAnon wrote:
       | "GOTO is considered harmful". This kind of thinking just makes me
       | want to run off screaming into a paper bag. Language developers
       | are, in many ways, the modern aristocrats telling us what we
       | can't or should not do. I still miss assembly language.
        
         | jjice wrote:
         | It feels pretty broadly accepted that overuse (or even moderate
         | use) of goto becomes a nightmare for readability. Plenty of
         | modern languages still support labels in loops to break to to
         | be able to break out of multiple layers, which is the only main
         | case that I can think of where a goto would be handy.
        
         | 12_throw_away wrote:
         | "Language developers are, in many ways, the modern aristocrats
         | telling us what we can't or should not do."
         | 
         | This is offensive nonsense and breathtaking entitlement.
         | They're providing you free tools to try to help you, usually
         | not even being paid for their work.
         | 
         | Edit to add: I just got copypasta trolled, didn't I ...
        
           | trealira wrote:
           | What's the original copypasta?
        
         | somecommit wrote:
         | I created a GOTO mecanism in rxjs once (typescript) but I felt
         | doing the wrong thing
        
         | Joker_vD wrote:
         | GOTO originally allowed one to jump across functions, into the
         | middle of the loops, etc.
         | 
         | And nobody stops you from writing in assembly! You'll just
         | spend more time on writing (and debugging) your programs but
         | sure, go ahead, it's not like your time on Earth is finite.
        
           | ithkuil wrote:
           | Fwiw, in C, switch allows you to jump in the middle of loops
        
             | nomel wrote:
             | In C, goto allows you to jump in the middle of loop [1].
             | 
             | [1] https://stackoverflow.com/questions/6021942/c-c-goto-
             | into-th...
        
       | jrm4 wrote:
       | Honestly, I _love_ this.
       | 
       | Precisely because there's too much gatekeeping in programming and
       | learning etc. Give people sharp knives and let them break things
        
         | pepa65 wrote:
         | I do LOTS in bash, and I have never missed Goto, haven't even
         | thought about it. And BASIC was my first language...
        
         | [deleted]
        
       ___________________________________________________________________
       (page generated 2023-08-03 23:00 UTC)