Updated 10/10/2015: This won’t make sense without reading part 1 first. In the first of these articles I hopefully got you to the point of having basic access to your Pi2 from a PC – and actually running a simple script that says “Hello”. From there on it’s just a case of building on this.
There are tons of ways to say “Hello” on a BASH script (simple text file) and echo is one of them – but it’s a bit limiting and some of the flags confuse the hell out of me – another way is to use “printf” – if you’re a C person this will be immediately obvious – it’s SIMILAR but not the same as the C printf command. On your command line you can have a go at printing “Hello”
See that last line. This follows on from the last blog entry… where we were logging in as ROOT and testing a script – that finally produced “Hello”.
So what’s gone wrong here? The “printf” version seems to have buried “Hello” in a line. That’s because printf does NOT assume you want a carriage return or line feed after your text… Like the C version you put them in with \r and \n as needed – and trust me they both have their uses.
This is the kind of control I like. In the first instance I’ve entered “Hello there” followed by newline – that works just fine in Linux… and you can see the result. In the SECOND example, I’ve entered “Hello there” followed by return – which takes the cursor back to the start of the SAME LINE - overwrites with some spaces – and then enters a new line.
So what could you use that for? Well, showing an incrementing timer on the same line for one thing – we’ll see that in use later. I is also easy to do right justification, colours and more.
I started to write scripts – then realised there’s a lot more to it than that – let’s say you want to capture a user password. There’s a command called READ which can put text you enter into a variable. In BASH scripts, variables are a bit weird, you update them by using them by name – but to access the information therein – you have to prefix them with $ - here’s a great example – in a script – collect someone’s name – and print it out….
But first I should explain quotes… single quotes take everything literally, double quotes are special and let you “embed” things in there, hopefully a picture is worth 1000 words.
I actually did this on the command line – and you can right now if you’re all set up – but the general idea would be to do this in a script. So the READ command lets me enter “Hello there” into a variable called fred. I can access fred as $fred… and you can see the text buried in there because I forgot the new line… but the magic is where I used double quotes and VERY simply accessed fred in the string!!! If it were not for the $ there would be no way for the interpreter to know that this was not simply the word FRED… method in the madness.
So being the type that thinks ahead instead of getting on with the job – I was thinking.. but… if I have this script and I use READ, what happens if I screw up the password? Well, with many scripts – you’re stuffed – and sadly you will come across scripts – within installation packages that do this – one mistake and you’re done… I can’t help that but I’m not having that in MY script.
So it turns out that you can have FUNCTIONS in scripts – and that you can have a text file full of functions – and even, if long and complicated enough, you can hide them away by simply “include” the file at the top of your script!!!
I discovered this lot by accident – in this case I’ve entered all of this on the command line.
Note that I’ve defined some variables (don’t ask how this works) and I’ve used one of them in my PRINTF command to add colour to part of the text !!!!
I also wrote a function to take in a user password twice, compare the two and only let the script progress when they are both the same!
So armed with this knowledge I set about making a script which would be modular – that would ask you for each part if you wanted to continue, skip the current section or give up altogether. At first I had all sorts of coding but soon realised you could hide much of the work away in an include.
So I ended up with 2 files – one called hackitt.sh which had my scripts in it – and another called my_script_includes.sh which had all the nasty bits hidden away – there is absolutely no reason why this could not be in one file.
So – taking one of the simpler examples… upgrading Linux to the latest version. As it happens I do this LAST in my setup script – but it’s an easy one to explain.
task_start "Linux Upgrade" "Upgrading Linux version..."
if [ $skip -eq 0 ]
My function task_start has 2 arguments ----and this is what you see when it runs… in this case I skipped doing the actual operation.
My “task_start” function does all the work here. It draws a pretty box and puts the FIRST argument into it – i.e. “Linux upgrade” – it then asks you if you want to continue, skip or cancel (Y/S/N) - and if you hit S for skip it goes onto the next section – remember my comments about moving the cursor on the same line – well, the elapsed time indicator uses as that – and the options are deleted when they are no longer in use showing a cleaner screen.
So – I call up my starter function – if I decide to go ahead – the SECOND argument is displayed – in this case “Upgrading Linux system”. The whole lot is wrapped up in a weird Linux IF statement (see the IF –THEN and the FI lines) – and in between is the actual scripting.. the second last line “task_end” merely puts an “[OK]” in colour in th right column if you go ahead and do a task. so the actual work is the simple instruction “rpi-update” and that is a built-in function in your Pi.
Most jobs are way more complex than that, involving installing something, maybe tweaking a config file, deleting some zip files when you are done etc. There is a tool called SED for replacing text in files – nearly killed me getting to grips with that – the worst part was that it operates slightly differently when you are running it on the command line to how it operates in a script!!!! However – the work is done. Having mastered just a few tools and making my own script functions, I can now just keep adding stuff into this script so that when it comes to starting from scratch with a new Pi2, I can sit back with a beer and simply fill in passwords on request, letting the Pi do all the work.
No doubt the Linux guys will come in here and tell me what I’ve done wrong – in which case the script will improve with time – and of course I’ll find new things to install etc….
It is beyond this simple blog to tell you how to use all of the various packages installed…. I’ll leave you to look them up on Google…. but if you get so far as to successfully run the script, the first thing you might want to do is go into webmin and update it to the latest version and maybe change the default template if you don’t like it – I could not figure out how to do that in the script. Webmin runs at port 10000… so in a browser you’d access your Pi by IP number and port … 192.168.xx.xx:10000 – you’ll be asked for the password you put in for Webmin and the rest is documented out there – I could not be without Webmin – good tool.
You may notice in my task-start, I spread some text over several lines – be careful with the placement of the quotes… you can have as many lines of text as you like but the quotes need to be on the same line as “task_start” or it will think you’ve not added any arguments and will then wonder what the hell that text is doing.
No doubt there will be bits I’ve missed out – and the script will change – but right now having written both parts of this in one early-morning start, I need coffee and food.