We techy folks are sometimes quick to pull the trigger when we spot people using tools without proper understanding. We laugh at Windows "point and click" mentality. Sometimes it may be justified, but I have to wonder if our own houses can stand deep inspection.
With that in mind, I decided to test my own knowledge of something I use every day: the Bash shell. I worked from a standard man page and read every line very carefully, asking myself just how completely I understood what I just read. I think that's a fair test: although I prefer Perl for day to day scripting, I do quite a bit with Bash. If you asked me to grade myself on Bash knowledge ahead of this self test, I would have given myself better than passing marks. I'm no stranger to the Bash man page, but I've never gone through it with this level of concentration.
I hit my first snag almost immediately:
Would you like to define a POSIX shell, Mr. Lawrence? No, I would not, or at least not without Google handy. Oh, yeah, I have a vague idea that the "P" stands for "Portable" and that the "OSIX" implies a Unix-like operating system. But what features are required of a POSIX shell? You've caught me slack jawed there..
Moving on.. what's this?
OK, that was a little hard to follow. I understand it, but I'm not clear on WHY you'd want to set parameters here. Why would I need to? Right after that comes a mention of the -D option, which supposedly prints out the "strings that are subject to language translation when the current locale is not C or POSIX". Really? It just seems to give me a shell that does nothing at all. A bit of Google research turns up the reason: it's not meant to be used interactively; it's supposed to examine a script (see Advanced Bash-Scripting Guide: Localization if you care.
We then skip along happily for a bit. Or *I* skip along happily. I have to pause again at that "--posix":
Err, what? Oh, yeah, make it fully POSIX. Vague memories start to come back.. it's stuff like "echo -n" and "echo /c", isn't it? Yeah, something like that..
Restricted shells, no problem. What's this?
Does that mean it picks out the executables in the script and finds out their dependencies? Apparently so.. I sure didn't notice that before and it doesn't exist everywhere. I happened to pick a RedHat based man page - I feel fine in ignoring this.
I almost got clear to "Definitions". Unfortunately, I ran into this:
OK, I see what happens, but why? And why wait until now to suddenly mention "-p"? This has to be something to do with security, but I don't know what.. I found a little clue at Effective UID changing... but why and who thread. I see the value - it prevents privileges picked up from a set[ug]id program from being passed to a shell that program allows you (or that you managed to steal from it). The program would have to purposely give you a "bash -p" to pass on its powers. OK, that's clear now.
Sheesh: I'm not even 10 pages in and I've already hit things I didn't know. But at least I UNDERSTOOD everything, right? Big pat on the back, let's take a look at those "Definitions", shall we?
Shrug. Piece of cake. Next? Reserved Words? Ditto. Do your worst, bash, I'm steaming up river now.
Aaargh. What the heck is this?
You know what stopped me there? It's the innocent "time" [-p]" at the beginning. Why is that there? That has nothing to do with pipes. And why the (optional) "!"? A paragraph or so down I learn that the "!" is used to negate the normal pipeline exit status - hmm.. if I ever knew that, I'd forgotten it. The paragraph after that attempts to explain why they mentioned "time" but fails to do the job. Are they telling me that bash is helping me out here by not just running "time" on the first element of the pipe and passing the output to the rest? Well, of course, but who asked for such special treatment? To me that violates protocol - it's not how it should work at all. I'd say that if you want to time a pipeline, you ought to put it in parens or in a script file and time that. I guess too many folks thought otherwise, right?
We went along happily for a while. I paused briefly at the description of BASH_REMATCH. I vaguely remember this. Bash's" =~" is familiar for someone used to Perl, so I can't claim not to understand this. Really, I'm doing better than I thought I would.
The section that begins with "Words of the form $'string' are treated specially." made me stop. Another "I did not know that" moment quickly followed by confusion upon reaching:
So I set and exported LC_ALL as "POSIX" and it doesn't seem to work. But I don't know what strings POSIX is supposed to translate, do I? So does this go down as "I don't know", "I don't understand", or both?
Here's a definite "did not know":
In other words:
$ cat t #!/bin/bash echo "foo$@foo"; $ ./t a b c d fooa b c dfoo
The explanation of $BASH_LINENO left me puzzled. I wrote some simple scripts that showed me what it does, but the man page says:
What's $ifP ? Never mentioned before this, and never after. This has to go down as "No idea what you mean".
I reached the section on file descriptors and expected to sail right through. But wait, what's this?
Cool! It works, even on Mac OS X with no visible /dev/tcp: here's an example script. OK, another "did not know".
I ignored all the "readline" stuff. It's probably crammed with things I do not know, but I just can't raise my interest at all.
Did you like that lie? How about something closer to the truth: Most of that whole section leaves me stunned and blinking. Oh, I know bits and pieces and can fake my way through some of the rest, but it's a big weak area. OK, that's definitely something I have to spend some time on. It's a bit overwhelming, but how hard can it be? Famous last words, yeah..
That brings us to the end of the bash manual. It certainly opened my eyes to some knowledge gaps. I'd hate to do the same thing with the big Perl Camel book!
Got something to add? Send me email.
More Articles by Anthony Lawrence © 2012-07-07 Anthony Lawrence