Shell programming with bash: by example, by counter-example
matt.might.net
matt.might.net
That said, I try not to do bash scripting. It's always been a boiling-the-frog thing for me: You start with a cute script with a couple of lines and then you make it more robust and add some more stuff and before you know, you've written a non-trivial program in an awfully quirky programming language.
But I'm still happy I've been there and know my way around bash fairly well. Makes for some pretty powerful quick one liners.
I think I'll add it in a revision.
I also agree on bash being quirky. I tell my class that the gold standard is a bash script that works 99% of the time.
Things like 'while read -r line; do {stuff with $line}; done'
These idioms have issues for their most common uses (e.g. dealing with filenames with embedded newlines), but they do work 99% of the time.
find . -type f -name foo -print0 | while read -rd ''; do
grep -l bar "${REPLY}"
done
find separates its output with the NUL byte when you do -print0, and -d '' means read NUL-separated input.Of course, in this case it would be better to use:
find . -type f -name foo -print0 | xargs -0 -I{} grep -l bar '{}'
but if you've got several things to do for each file, the first one makes sense (or you can put those several things in a script, and use xargs).If your guide is for bash and not sh, then I would say don't teach them [, just do [[. It's safer, since it won't glob or split words, you don't need quoting, and you don't need to escape operators like < and >. Maybe it's can be seen as more difficult since it's a sublanguage (doesn't use the regular syntax rules), but so are (( and $(( which you've discussed at length, and which are typically less useful than [[ in bash.
https://github.com/yesodweb/Shelly.hs/blob/master/README.md#...
[0]: http://search.cpan.org/~toddr/IPC-Run-0.92/lib/IPC/Run.pm
$ declare -A capitals
$ capitals["Illinois"]="Springfield"
$ capitals["California"]="Sacramento"
$ echo ${capitals["California"]}
Sacramento
$ echo ${capitals["Illinois"]}
Springfield
$ for k in ${!capitals[@]} ; do
> echo "The capital of $k is ${capitals[$k]}"
> done
The capital of Illinois is Springfield
The capital of California is Sacramento#!/bin/bash
echo "Content-type: text/html"
echo
echo "<pre>"
(Run some CLI status type app here, or du -m a file or whatever)
echo "</pre>"
exit 0
Doing "web stuff" could be exciting for the learner.
(edited to add, doing "modern" web development in BASH might count as one of the counterexamples, no matter how fun and easy it is)
Since I'm using these as lecture notes for my class, I'll try to add it in before I teach today.
If on a *nix platform try df for your cli app. This was "state of the art remote monitoring" where I worked in the mid 90s. Also http://whatever/cgi-bin/uptime displayed about what you'd expect. And the dmesg script, another handy one that is about what it sounded like.
Next step is there's a lot more HTML codes than <pre>. So put stuff in <h1> etc. Before <blink> was censored I used that occasionally.
A fun next step is commands with mysterious and unclear outputs. Like grep. Maybe grep a log file. Will you get no lines or a thousand lines? How do you intend to inform the user that either the CGI crashed or there is in fact no lines to output.
After that a bunch of if/then based on the output of grep -c
If its not fun to output text based on some if/then I'd try img tags. So now something broken is a red down arrow. And a giant frameset of multiple machines multiple tests is kind of an alert board, sort of. At least in 1997 or so.
You can make an interesting display of security problems by stashing temp files and temp scripts and temp things in /tmp... what could possibly go wrong with trusting the contents of something in /tmp, LOL?
Although I forget exactly how (its been awhile since BASH was a cutting edge web framework) there's a way to access http parameters so you can do simple forms that ask for something to search, then run grep on that passed parameter, then format the grep output to an attractive level. And of course you can pass "funny" parameters to the script which probably does no input checking and introduce them to Bobby Tables meme and all that.
I didn't do this, but in the years before phpmyadmin I worked at a place that basically had a script that ran whatever you passed it as a command for mysql. As root. With no authentication. And of course a hard coded password in the command line for anyone running "ps" to see. Yeah. It was one of those things that the developers thought was awesome for dev work on the test server but somehow snuck off the test server. That was a funny one, nothing bad happened, but could have been bad.
This kind of stuff is a bit safer on a private lan than being tested out on the internet, but everyone reading this probably knows that...
Most bash tutorials I have seen seem to be taking forever to get to the parts I usually need a quick refresher of.
A very good quick start/reminder/advanced cheat sheet, good work.
I created these as the lecture notes for my class this morning.
Is this markdown -> HTML or pandoc or your own static generator?
test -e "$file" || {
echo "file not found: '$file'" >/dev/stderr
exit 1
}
etc.ed. "indispensable" got it.