It does have a small problem in the number of "bashisms" that it quietly promotes.
The entire Debian/Ubuntu family has chosen the Almquist shell because of speed and standards compliance, and many things in this book will not work there.
It would be helpful to have a book that is clear that the POSIX.2 shell is not Bash.
So Debian/Ubuntu ship completely without Bash? According to [1], it's Bash, but it might be outdated.
What is shipped as /bin/sh is described here:
http://gondor.apana.org.au/~herbert/dash/
From the EPEL RPM:
"DASH is a POSIX-compliant implementation of /bin/sh that aims to be as small as possible. It does this without sacrificing speed where possible. In fact, it is significantly faster than bash (the GNU Bourne-Again SHell) for most tasks."
I think the bigger stumbling block is that people often can't differentiate bashisms from basic shell scripting.
I agree about the importance of differentiating bashisms from basic scripting, but I think the root cause of that is documentation (including this book) that don't make the distinction.
I'm not trying to be difficult, but I just don't see a problem. Explicitly use bash (or a derivative) if you want bashisms, don't if you do not.
Both are spiritual descendants of Bourne shell directly, with some ksh, csh, and tcsh mixed in, in varying proportions.
``` ubuntu@primary:~$ uname -a
Linux primary 5.15.0-56-generic #62-Ubuntu SMP Tue Nov 22 19:56:13 UTC 2022 aarch64 aarch64 aarch64 GNU/Linux
ubuntu@primary:~$ echo $SHELL
/bin/bash ```
dash is the default `/bin/sh` but the default shell is still bash. (man sh gives you dash's man)
This is different from /bin/sh, which is Almquist.
Maybe the one thing I love about Linux culture (compared to the BSDs, illumos, etc.) is that it generally doesn't require everyone to adhere to some high UNIX religion.
Writing a shell script of more than 50 lines is hard to do correctly. Bash sometimes makes that a little easier. And it's almost ubiquitous. Forcing new Linux users to learn a POSIX compliant shell, when they are only likely to be using Linux and bash, is simply cruel and unusual. Just as including only `vi` in the base system instead of `nano` is a silly self-own.
I see this unreflective question far too often: "Why aren't people using my system and using Linux instead?" And the answer is pretty simple, Linux at least made efforts to reach out to people where they were, in hundreds of low effort ways, whereas your system probably didn't.
"Everyone should be using Linux" and/or "should love the command line" is pretty silly, but just as silly is "people should learn the POSIX shell" first. A shell they are likely never to use interactively. Because of a hypothetical portability concern? It's nuts.
Where did the GP make that assertion? I don't see anywhere in the post where they say "please rewrite all the shell examples in POSIX-compliant sh". All I see is a request to inform the reader that not every shell is bash.
In the UNIX Wars of old, Sun and AT&T attempted to take unreasonable control of System V, which included the Korn shell.
DEC, IBM, HP, and others responded with POSIX.
https://en.wikipedia.org/wiki/Unix_wars
The impact upon the Korn shall was actually to reduce functionality, and a number of features were removed (arrays, coprocesses, etc.). The reason for this is that the source code for the Korn shell was configured to compile to a 64k text segment (for 286-Xenix), and readability/maintainability was sacrificed.
Due to this lineage of the POSIX shell, it is very friendly for embedded systems and other constrained environments in ways that its descendants and competitors are not (and can never be).
It deserves to be distinguished from Bash, without question.
Absolutely, and I agree with your sentiment at a broad level -- although I think the book notes who the book is for, and that `bash` and `sh` are distinct, it doesn't explain the why of maybe considering `sh` for other uses which aren't really the focus of the book, and perhaps it should?
> Due to this lineage of the POSIX shell, it is very friendly for embedded systems and other constrained environments
I'm wondering if this will matter as much in the future. Are people really going to be programming 16 bit microcontrollers when a 32 bit parts are becoming so cheap? How constrained are we really going to be?
C:\Users\chasil>busybox bash
~ $ a[1]=1
bash: a[1]=1: not found
~ $
Despite what Busybox claims, that is very much not Bash. That is Almquist, with a few added bashisms.I was in a clothing store a few months ago, and their credit card readers had crashed. They were showing the Busybox copyright notice.
a[1]=1
$ echo $SHELL
/bin/kshThis is mksh from MirBSD under Hyperbola Linux.
Giving DEC, IBM, and HP credit for POSIX is a little odd. They were actually the biggest beneficiaries of the fragmented nature of Unix, with their proprietary flavors. AIX vs HPUX vs DEC Unix all meant that Ken Olsen could pretend to support Unix and at the same time tell the world that "Unix is snake oil".
I did!
If your environment somehow lacks bash, consider that the bug, and get bash.
Or, untie both arms, and use a language that's not going to take every opportunity to stab you in the back with subtle idiocies dating from the last millennium.
(But I do agree that, if you're going to put down a bash-ism, it's bash, not POSIX sh.)
https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V...
if enough people decide to just use bash, then that will be the new standard. we don't have to ask for some committee's permission to advance.
It does have something of a split personality on that question.
Are you still referring to bash here?
if you can't even do that, maybe reevaluate what life choices got you to this place. life is too short to write strictly posix sh.
Many non-Linuxes, and some Linuxes too.
> why can't you just sudo apt install bash
Linux is not the whole world. Debian is not the whole Linux. Interactive shells on servers are not guaranteed to be available. Control over the installation image is not guaranteed, or always desirable.
> life is too short to write strictly posix sh
Alas. Life is too short for writing or responding to uninformed rants. Yet here we both are.
POSIX shell scripting has its place. It's not as difficult or complicated as you imagine. The portability tradeoff is valuable or essential in many real-world cases.
which ones can't run bash?
>Linux is not the whole world. Debian is not the whole Linux. Interactive shells on servers are not guaranteed to be available. Control over the installation image is not guaranteed, or always desirable.
I didn't literally mean "sudo apt install", I meant "install the thing by whatever means is appropriate to the platform". if you can't install anything then what are you actually doing with it? you have to get your software onto it somehow.
and at any rate, the article is literally called "the Linux Command Line"
>The portability tradeoff is valuable or essential in many real-world cases.
like what? seriously, what?
I don't get it. I understand software that has weird/harsh requirements because it's on a super constrained embedded platform. that's a real limitation. but being able to run posix sh but not bash seems like an entirely artificial problem. there's no rigorously conceivable resource constraint that would do that. if your unix is so fucking degenerate that it can't run bash then that's a problem of your own choosing.
anyway if it's so easy, you can take on the burden of porting scripts from bash to sh yourself, instead of annoying the rest of us with the "bashisms" whining.
bash is usually convenient. When it's not convenient, it might be impossible. Shell scripts with long lives or broad usefulness should be portable.
POSIX sh is just not that scary. It just takes a little extra discipline. It's an appropriate choice, more often than not.
The MirBSD Korn shell, mksh, is used there as the system shell.
That footprint is huge.
Some utilities that I have used on Android bring a copy of Bash along, but it's not standard.
I also mentioned above that I do some shell scripting with Busybox-win64. I can't use arrays in the "bash" that it implements.
I've also worked on routers that use the Busybox shell, same problem.
Dash is also far smaller and advertised as 4x faster than Bash. Anything I write that targets dash will run on all the others, so this skill is quite useful.
The downside is that once they're welcome, the climb of the learning curve is barely started.
It's definitely not obvious if you're used to having separate fields, but it's a bit unfair to complain about all GUI clients because an opinionated text input box is missing from a single feature from one of them surely?
For me, it's hard to make good software today because the bar is actually higher, in the sense that it must be usable by a much wider audience and I can't be lazy about usability or even worse, let it unnecessarily complicated because "people should know about it or learn".
Fixed it for you: [...] and WHEN it isn't they LEARN.
I don't have this problem with the equivalent libraries in the programming languages I use, give me 'easy mode'. We need new binaries with a modern UX, or a better IDE for using the command line.
Asking because I'm at a bit of a crossroads - I have a good handle on about 5% of the command line knowledge which gets me through 80% of the stuff I need to do. I'm wondering if learning to use more commands is worth the effort when I can already get the task done without using the command line?
I suppose it's a super rare occurrence now, but back when I was starting on this, I would mess up my X server and was forced to fix it from the command line.
If you get a sense of things you can do with (|, & , >) and a dozen or so commands like
sort | uniq | cut | paste | join | head | tail | sed | awk | wc | tr | fmt | col | nl | pr | find | grep | tar | export
The value you get in return is intense for the effort invested.
Plus, in the 10 years i've been maintaining code, bash scripts are the minority that still work as they used to with almost no change needed.
That single handedly is worth my money.
A lot of cut invocations I see are on CSV files, and are all bugs out of the gate.
(But use JSON, if you can. It's a step up, and easier to work with, particularly with jq.)
I've seen hours wasted writing jankey one off c++ utils, for lack of knowing that grep/awk exist.
Being able to tail a dev log and filter it for errors is also a part of seasoned developer competence too, I'd say.
E.g. there was a time in my life when I didn't get what `xargs` even did, I literally couldn't grok it. Now, I can't imagine life without `-0`!
The composability of UNIX commands is just so amazing. Every command builds on every other command. I haven't seen that with any other tools or program.
e.g.:
find . -type f -print | xargs wc -l
vs. find . -type f -print0 | xargs -0 wc -l
If you have filenames with whitespace, the first will skip a bunch of files.If you're doing processing on other inputs which may include whitespace, you'll be able to handle those using xargs without worrying about additional delimiting.
And for those not aware, '-print0 / -0' arguments to find(1) and xargs(1) respectively tells the first to output ASCII NUL delimited arguments, and for the latter to expect the same. As ASCII NUL should not normally occur within any argument, it's the ultimate delimiter.
I've used xargs and/or bash loops to do some fairly heavy-duty web scraping given an input list of arguments. Using xargs allows multiple simultaneous parallel queries such that any one request stalling out doesn't hold up all process.
"wc -l" gives a line count for a file. That's ... not especially advanced, but is a trivial example of an xargs command which you should be able to try without causing any problems on your own system.
It lacks many things provided by a POSIX shell (nearly all of which are present in the later Korn shell).
There are many entire operating systems that survived only a fraction of this time. I think that it will remain relevant for decades.
Command line programs compose like this, GUIs don't.
For this and other reasons, I will often write programs as command-line using standard I/O for most data. For example, a music playing program which reads the music file from stdin and writes the audio data to stdout which is taken by aplay to play the audio on the speaker. (In this way, you can also add other thing in between such as special effects, if desired.)
(It is also useful for other programs (interactive or GUI or whatever) to have the opportunity to open pipes with other user-specified programs; Meirloom-mailx is one interactive command-line program does it (I often use that feature to display pictures attached to messages), and Free Hero Mesh (which has GUI) also exclusively uses such pipes to import/export levels and pictures and move lists.)
The rest of the book offers a somewhat longer-form answer.
Another reference I'd strongly recommend is the O'Reilly UNIX Power Tools book, which though it turns 30 as of the new year remains one of the best "what are some really useful recipes" books about and for Unix / Linux.
That is freely available here (3rd edition):
<https://mathcs.duq.edu/~juola/UnixBooksPDF/unixpowertools.pd...> (PDF)
* M-Windows WSL2
* Cygwin
* Mac OS X
* ChromeOS Crostini (Debian Linux VM)
* Linux (of course)