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