Why shell sucks
I’ve written a few toy programs in shell – I’m marginally proficient, at least. Or, too put it another way, I’ve found where the manual is…
I’ve been considering a new build system for Takahe Linux, or at least a refreshed version, so I was wondering what to write it in. Currently, I’m using a shell script that works. That’s about the only positive thing I can say for it!
Actually, it’s not too bad. The problem is that I can’t see any half-decent way of adding some features I’d like – namely, dependency handling – without making a mess of what is a relatively simple shell script.
Anyway, I ended up writing a list of things I disliked about shell scripts – a list of things that make shell scripting suck. Some are just annoying; others can cause catastrophic failures (read – data loss, corruption, general pain)!
- No array datatype! Actually, having everything as a string can be annoying, too.
- Unassigned variables can be accessed.
- Lack of clear namespaces.
- Lack of multiple return variables.
- Too many interactive functions (just general language bloating…).
- Awkward (arguably non-existent) multi-threading support.
- Syntax is not at all forgiving – forgetting to quote something properly can be bad, for instance. And it can even work, until that moment where it doesn’t… and you suddenly loose files because a directory had a space in it’s name!
- Slow. This is not really an issue…
- Error checking is weird. For instance, by default, failures in a pipeline are silently ignored in Bash.
- There are many, many different shells. All of which behave differently for different things…
- Colour is nice. Until it breaks another script…
- Parsing the output of commands is inherently prone to breakage!
- You have to learn the syntax of lots of sub commands just to get something to work. Or languages within languages; sed, for instance!
- There are no libraries. You have to use commands instead. Which can be really inflexible (how do you propose to pass <insert complex datatype here> to that command, and how are you going to parse the complex output in a sensible way?).
Just to show that I’m not completely against shell scripts, here’s why I do use them:
- Light. Bash has a 4MB memory overhead on my system; dash 2MB. Python uses 10MB… on a good day.
- Simple. Kind of. For some things…
- File-orientated, which can be quite nice.
- High level. Writing some of the simple stuff in C would be even worse than writing it in shell…
Generally, though, I’d like a scripting language that was a ‘real’ language – with proper datatypes, better error handling, and so forth. So I went looking for ‘sane’ alternatives.
Here’s some that I found:
rc is lightweight (1MB RSS), and it supports arrays. It still is a shell-based language, though…
lua is not designed for shell scripting, so it’s a bit awkward. In terms of performance, it’s one of the best interpreted languages, and uses ~2MB RSS on my system.
perl is well known as being a messy language – even more so than shell. It is, however, heavily designed to be a replacement for shell scripting, so it’s possibly the best fit. On the other hand, if perl, why not rc? Perl is about 4 times as ‘heavy’…
Generally, none of those options sound attractive. Lua’s probably the best bet, because it places value on correctness, at least in comparison, but shell scripts directly translated into lua are very verbose!
What I’ll probably do is see whether I can make make work. Or perhaps just become really frustrated…