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