Certainly there's a lot of stuff in common. I read every single article on Greg's Wiki a couple years before starting this book, and it's informed a lot of my opinions and understanding of the fundamentals of Bash. I do disagree with what seems to be the prevailing wisdom on Greg's Wiki on some points though. For example, I strongly support using errexit rather than trying to implement all the error handling yourself.
I agree, Greg's Wiki has a lot of amazing content. Certainly there will be a bit of overlap, but the focus of the book is a bit different:
- It is more relevant for scripting than the interactive command line. For example, it includes
- I've taken a lot of care to write non-trivial example code, which is useful to show when and where constructs are useful, and which other constructs they are usually used with. For example, the argument parsing part shows not just how to use `getopt`, but also how it's meant to be used with `eval`, `unset`, `while`, `case`, and `shift`; the standard `--` option/argument separator; how to handle unimplemented options (anything mentioned by `getopt` but not matched by any `case` statements); and how to deal with the remaining arguments.
- The non-trivial code has been linted using `shellcheck` and a lot of it is tested with `shunit2` (533 lines of tests in total, which are included as a download).
Thank you for the feedback! It's not a beginner's guide; it really is intended for people with at least a reasonable understanding of programming concepts such as scope and the difference between imperative and other types of programming.
Maybe you are right, but I don't think you and the publisher did justice to your book.
It's clearly a course - 99 lessons, wow! First look at the index may confuse potential reader. It's about signals and copy and paste at the same time. Copy and paste actually CAN be tricky and is mostly not well understood for people not raised on a Linux desktop. But the headline itself confuses me and my first though was that it's more of a beginner course like those RedHat has at the begging of the certification path, before tests start. - what is console, what is Gnome, files, users, groups etc..
What usually made me interested in such products was a clear, full chapter that I can read. Even better if it's an actual chapter that can be used individually, without the context of the rest of the book. Not the introduction. It is usable on it's own, so it's linked by people - that is some good publicity. It worked on me and some of my friends!
Also how does it compare to other books, like https://tldp.org/LDP/Bash-Beginners-Guide/Bash-Beginners-Gui...? Yours looks like for beginners but it's just targeted towards devs that don't know bash and linux terminal well. The linked one is titles "for beginners" but it's not really :)
I hope this gives you some insight that you can use in future. I really didn't wanted to just complain in vain. Some of my friends wrote large IT books and I know how weird experience it is to work with a publisher. Good look!
No worries - the book grew out of a Bash course[1] I developed and ran at my previous and current employer, which mostly goes through a bunch of WTFs and non-trivial syntax and solutions to common problems which turn out to be more subtle than the naive implementation would indicate.
I haven't read the guide you linked to, but scanning the index I'd say my book is quite different:
- A big portion of my book is about quality assurance - exiting early, automated testing, linting, the most readable forms of commands, and the like.
- It's focused much more on scripting than command-line use.
- It avoids common pitfalls like using `which` to determine what will be run[2].
- Rather than give a surface treatment of `sed` and `awk` it treats those as separate subjects which would be better learned from some other source. Personally I avoid `sed` and `awk` in scripts where possible, since a lot of the things they do can be achieved with more maintainable commands, anything non-trivial is really hard to read, and using either is an indication that the problem might better be implemented in another language.
- It's opinionated about interactive scripts. Basically I consider them a bad idea the vast majority of the time because they pretty much preclude wrapping in a sensible way, and add a bunch of extra code irrelevant to solving the problem.
> It is not even theoretically possible to write a piece of software which will behave the same no matter how and where it is run.
Can you elaborate on that? I'm sure it's both true and false depending on your definition of "how and where it is run," but wondering what you had in mind specifically.
As for the "theoretically" part, it is enough to prove that at least one such a system exists that will yield another result than expected. There could be various reasons, from human/software errors to hardware errors like memory bit flips. Since we know these do exist, it is not even theoretically possible to write a piece of software which will behave the same no matter how and where it is run, although it is certainly possible to write it in such a way that it will behave the same in a vast majority of cases.
I'd say that containers are actually something that makes Unix shell a lot more valuable and predictable, and one reason that I'm working on https://www.oilshell.org/ .
A container is basically a "virtualenv" for shell, and it's honestly better than that because:
- it's more general (it isolates every language, not just Python), and
- not even bigger (e.g. an Alpine Linux container is not that much bigger than the Python install in every virtualenv!)
Traditionally you do indeed have the problem that copying a shell script from one machine to another basically guarantees you nothing about how it will work. These days we deploy containers, which solve the problem, and that's why shell is used so much in the cloud (e.g. anything with Github Actions has a boatload of shell)
I remember reading (sorry, can't remember the source) that it's been proven mathematically that there's no way to write code which will run the same on any Turing-equivalent processor. Obviously that's not saying much since Bash is pretty far abstracted from the CPU, it's more of a caveat that I've hardly ever seen a discussion about Bash which doesn't involve at least one "well, actually" comment about how the suggested code doesn't do what the autor purports on some incredibly niche platform or with some highly unusual configuration.
Slightly off topic, is there a nice/modern way to deal with filenames that can have spaces in bash scripts? The only solutions I have seen use tons of quotes are are unreadable/unmaintainable.
You can set IFS='' globally, which disables splitting. (And you have to make sure it stays that way, since there are some idioms which modify IFS)
Although there is the "empty elision" case related to splitting: if x='', then $x is different than "$x", even if IFS=''.
You could also use zsh which doesn't do word splitting, but does "empty elision". (I'd say zsh is a better interactive shell than a scripting language, but I've seen it used on occasion.)
Or you can use OSH, which will run your bash script as is. And then you can opt into shopt -s simple_word_eval or the group shopt -s oil:basic, and EVERYTHING will be "unmolested", quotes or not:
I strongly recommend the book Unix Power Tools for all such questions. Quotes become easier to grok once you think of different ways to remove meaning of special characters. Basically, 1) backslash removes special meaning of the next character, 2) surrounding by double quote removes special meaning of all characters except backslash, dollar, and backtick, and 3) surrounding by single quotes removes all special meanings.
I'm afraid quotes are the way to go. The alternatives are basically escaping (which looks even worse) or using a different language. The book also mentions a few more tricks you probably want to know about for dealing with the really tricky stuff, like filenames starting with a hyphen or ending with a newline.
This one hopefully has a bit of an original twist by being focused on maintainability and understanding some of why Bash is different from most programming languages, and by being aimed at software developers mainly working in other languages.
I'd like to write a follow-up article about the process of getting there if there's any interest. AMA.
Chances are, it isn't.
https://mywiki.wooledge.org/BashGuide
https://mywiki.wooledge.org/BashFAQ
https://mywiki.wooledge.org/BashPitfalls