Russell Coker writes about shellscripts. I have a different suggestion. Whenever you think that a shellscript is the right solution to a problem, you are mistaken: do it in a proper scripting language instead. Having access to proper data structures will mean you don't have to contort your code to fit values into scalar strings, or write loads of temporary files, or call cut/awk/sed/grep etc. repeatedly on the same inputs to get at different fields, etc. etc. etc.

I reckon nine times out of ten it's the right decision. But when you just have to use a shellscript, use set -e (as Andrew Pollock points out, this is safer than putting it on the hashbang line and set -u too.


Comments

Shell scripts do have a place - if there is any possibility that the script will need to be executed in an embedded environment, all interpreters will have been removed, even perl (see http://www.emdebian.org/crush/) let alone horrors like python etc.

There is a good reason that debootstrap is shell - another that would be very useful in shell instead of perl is adduser.

The only other alternative is C, even C++ is sub-optimal, which is why we have cdebconf.

-- Neil Williams

codehelp [launchpad.net],

I disagree, for no other language integrates as tightly with the Unix principles as shell; no other language makes it so easy to connect processes via a pipe, redirect file descriptors, call external programs (this is Unix after all), and be debugged.

Yes, scalar variables suck. bash, and even better, zsh offer useful alternatives. There is no type safety, but then again that's a trade-off for the aforementioned benefits.

Point being: use shell if you pass data between programs; use something else if you need to manipulate in-memory data.

-- madduck

madduck.net,

While shell scripts may often be bad, shell programmes can solve even complicated problems easily and are much more maintainable and easily debugged, in contrast to scripts (Perl, Python, shudder PHP) or compiled programmes. POSIX shell isn’t good for them though; use either mksh, ksh93, or zsh.

“set -e” and especially “set -u” are bad though, especially in POSIX shell scripts: “set -e” is known to be broken in various variants of legacy and not-so-legacy shells, and “set -u” is even worse: the only sane definition of it will only be in a future POSIX standard (mksh in testing implements it, as do a few other shells, ksh93 either does or will), so no standards- (as in POSIX 2008 / SUSv4) compliant shell does it correctly.

While I agree that “set -e” and “set -u” have their merits, please only use them while writing and/or debugging your shell script or programme, and turn them off in production code. Write your code robustly instead.

If you think you’d like to code for GNU bash, consider at least looking at mksh first. It’s much smaller, faster, embeddable (copycenter licence, not copyleft), and offers more functionality and not much not that GNU bash does (associative arrays will be there in the next release).

Sure, I develop mksh. But my stance on this is: shell scripts are not portable, but this shell is (it runs on Minix, DEC ULTRIX, etc. after all!), so I’d rather write mksh scripts or programmes.

-- mirabilos – http://mirbsd.de/mksh

mirabilos [launchpad.net],

hello, thanks for your comment. To be honest, if the problem you are trying to solve is large enough to warrant differentiating between testing and production code, I am of the firm conviction that shell is entirely the wrong tool for the job. I do not agree that there is an inherent property of shell scripts that make them more readable/maintainable than scripting languages. From experience, the various shell scripts I have had to deal with that are written by others are true nightmares, and full of insecure things like $$ for tempfiles, etc., multi-screen branching conditions, sparse use of subroutines, etc. Whereas stuff written in scripting languages -- even perl -- are generally written in a small enough language subset to be clear. Of course it's entirely possible to write unreadable code in any language. I am thankfully spared reading or writing PHP most of the time.

Interesting stuff about the compatibility issues of set -e and set -u. I was not aware of those. That encourages me to avoid shell even more. -- Jon

Jon Dowland,

Hello, thanks for the comment. I agree that no non-shell language has made piping programs together as easy or natural as shell. This is an area which I think many scripting languages could improve on, perhaps even just a good library for it. I also agree that for some tasks, a sequence of call-outs all wrapped in (e.g.) os.system("...") is fairly awkward.

Perhaps the jobs I find myself doing naturally lean towards more heavy data processing these days, rather than just playing pass the parcel between programs...

I'm not sure I agree with you about the file descriptor stuff, although I rarely have to do much manipulation here, it would appear that the file handle approach in many scripting language is superior to the insane exec 3<> File; foo >&3; exec 3>&--style stuff. -- Jon

Jon Dowland,

Hi Neil, thanks for your comment. To be honest I don't agree with this argument. Obviously there's a balance to be made, but I that constraining yourself in the general case for the possibility that the script might find a use on an embedded system is optimising for the wrong eventuality: the pain of rewriting into shell when the script does need to be present would be felt less often. You would also have the advantage of having explored the problem space with all the benefits of the real language before settling on the shell script. -- Jon

Jon Dowland,

I agree, shell code written by others is often stomach convulsing. But then, scripting language code by that kind of people is ofteh unreadable in addition to that… -- mirabilos

mirabilos [launchpad.net],

Oh, btw, I've never really used korn shell before, but there are a few bits of it lying around at work, particularly in the Oracle/SAP systems. I'll be sure to give mksh a looK! -- Jon

Jon Dowland,

Thanks! You might like (attention, rather ancient code, things have progressed ever since, especially in mksh, some in ksh93) this one: http://www.mirbsd.org/cvs.cgi/contrib/code/Snippets/oracle-ksh-access.shar?rev=HEAD;content-type=text%2Fplain I think SQLplus is superiour to most other similar tools (such as psql, cornfedsip, cadaver) for its simple scriptability and the option to change the prompt (in the same line as the command) to signal end of input. And note that mksh isn’t probably installed, but easily compiled. -- mirabilos

mirabilos,