Welcome, Guest. Please login or register.

Author Topic: THOR's Shell Hacks  (Read 36780 times)

Description:

0 Members and 1 Guest are viewing this topic.

Offline Boot_WB

  • Hero Member
  • *****
  • Join Date: Feb 2005
  • Posts: 1326
    • Show all replies
    • http://www.hullchimneyservices.co.uk
Re: THOR's Skip Lab
« on: February 20, 2015, 02:20:04 PM »
Quote from: Thomas Richter;783069
Today, I'll try to cover a bit a dark edge of the Amiga Shell, and these are the two commands "SKIP" and "LAB", and why they sometimes didn't work before 3.9. Of the two, LAB is actually not a command at all - or rather,  it is, but it doesn't do anything, while still being necessary.

Flow control - that's a key feature of every programming language. That is, to control where program flow goes. "if-then", "for-next", "do-while", "repeat-until", this kind of stuff. Unfortunately, the only thing AmigaOs has is "if-then", and "goto", even though the latter is pronounced "skip". It's the same ugly command that has been banned from many more reasonable languages for good reason - it creates spagetti code.

Anyhow, it's all we got, so here is how it works: If you have a "lab foo" somewhere in a shell script, then a "skip foo" continues control to this very position in the script. Simple enough? Not quite. If the label is *above* the skip command, i.e. on a line "higher up in the code", you need to say "skip BACK foo".

Simple enough? Not quite. If there is an "execte" somewhere between the label, or you are calling a shell script by some other means - probably because you have a file whose 's' bit is set, it doesn't work at all. Or at least, it did not *used* to work before Os 3.9 latest BoingBag.

Why now does the freaking shell care about execute or not? That's again one of the sad stories of "bad design decision". Remember, commands have an input stream, and an output stream, you can redirect with "<" or ">". In  a sense, the shell has the same: It has an interactive input, which is the console the user types on and the shell connects the input of commands it executes to. This is the console. This stream is used for the "ASK" command, for example, to read user input. But the shell has *also* a command input, and this is where the commands for the shell come from. That's usually also the console, as the shell executes the commands as you enter them.

Now, however, if you execute a script (explicitly, or implicitly by a set s-bit), the shell does the following: It connects its "command input" to the file of the script. Sounds like the easiest thing to do: Magically, the input comes now from the script file. Since the interactive input is still connected to the console, the "ASK" command and all other commands still receive that as standard input, and hence read their input from the console as they should.

That's all pretty lean and neat unless... you want to execute a script from a script. Ooops, what do we do now, the CBM engineers said? They came up with the bloddiest ugly hack you can think of: Take the script to be executed, copy that to the RAM-disk (actually, T:), and append the rest of the script that is currently executed (and hence, the script that calls the other script) and append that at the bottom, then execute the new script.

That's just so wrong. I've written some hacky scripts, but even I wouldn't consider that a 'solution'.

Quote
See where I'm getting? Since the top of the current script is lost, and hence any "LAB"  command is lost, a "skip back" to a label that is below any execute command cannot see the "LAB" anymore, and hence, cannot skip back.

Luckely, the 3.9 shell is smarter, and does what every proper programming language does with recursion: It keeps a stack. Thus, yes, you can "skip back". In case you care, the stack is kept in some shell variables (you can see them with the "set" command, to be discussed in a later edition).

What the 3.9 shell does not is to "get away" with skip, and introduce *useful* flow control, as in "for" or "while". It would not be overly hard to do, but simply was not done. A bit of tradition still had to remain, I'd say.

Excellent summary Thomas, thankyou.

WaitX (Aminet) is also damned useful for creating cleaner scripts if anyone needs a bit more flexibility than 'wait' provides (often used with skip...lab).
« Last Edit: February 20, 2015, 02:22:38 PM by Boot_WB »
Mac Mini G4 (1.5GHz, 64MB VRam, 1GB Ram): MorphOS 3.6
Powerbook 5.8 (15", 1.67GHz, 128MB VRam, 1GB Ram): MorphOS 3.8.

Windows-free since 2011-2014 (Damn you Netflix!)