< Index

Everyone should learn POSIX shell scripting

Every once in awhile I'm exposed to a Windows installation somewhere - like when I was still going to university, or when I'm made to use a work computer. One of the games I like to play in my head while suffering through this tramatic experience is trying to see what particular, nameable things I don't like about Windows compared to my bog-standard KDE Plasma systems on Linux. Now... this isn't really hard to do, since you're staring at a maze of dark patterns doing any basic task on Windows. Some of them are so evil I don't know how anyone thinks this is okay, like how when Microsoft asks you to backup your system, the selection in the dropdown you have to pick to get Windows to leave you alone for a month about doing backups hovers directly over the button to immediately start backing up. Anyways, the one thing I always, always miss when I'm using a Windows system instead of a Linux system is the ability to easily script out long sequences of commands.

If you're using basically any system that's not completely locked down and isn't Windows, you have access to POSIX shell scripts. The POSIX shell is not an actual piece of software so much as it is a publicly available standard that all conforming shells must be compatible with. Any system that calls itself UNIX or Unix-like is going to have some level of compatible POSIX shell. For Linux systems in particular, most people use zsh or bash which are just feature supersets over the standard POSIX shell. Even macOS is technically a compliant UNIX system, and thus has fully certified POSIX shell compatibility.

For the POSIX shell, one of the capabilities that it has is to read shell script files in regular UTF-8 encoded text and interpret them on the fly with their own simple but effective programming language. Basically, you can set the executable bit on a text file and pass it to the shell and it'll interpret it as if it's a whole programming language, and to the user running the script there's no indication they're not using any other terminal program. This gives you a way to write simple programs that are extremely portable to other systems, not requiring system or architecture specific compiling and also not inherently depending on any particular system's behavior. This capability to write standalone executable scripts is shared by other shells like bash and zsh, but writing in those shells inherently limits your portability to only other users of those particular shells. Some people argue that you should target bash since most Linux systems and all GNU systems use bash, but I don't see any reason to single out the *BSD users, and I also haven't yet found any killer feature in bash that made me really need to write a script in it. So, I write POSIX scripts for everything and keep my options open.

Under this website's Files index, I currently have a Fedora update shell script that automates all of the different processes in a normal system update for a Fedora Linux system. The question I think people might have is, why do it this way instead of just using a graphical package manager to update your system, like KDE Discover or whatever else? The answer is that what those tools are doing basically boils down to a long chain of individual smaller commands, and when you break it down and string them together manually in a shell script, you're able to go back and comment out specific lines or give richer output on certain steps or do whatever you need to do to make your system task go as smoothly as possible. It can be clearer and easier than trying to run the closed off tool and then debugging afterwards if something goes wrong, not knowing at what step the update crashed on because you're not able to easily set debug messages.

That's really the difference here. Let me go on a bit of an anecdote. At my last job I had to setup recycled laptops for sale with Windows 11, and the process involved setting up a ton of software and then running the horribly slow and terrible Windows Update like 8 full times until it eventually stops updating again. All of this stuff I had to do manually, clicking icons, unchecking options, bypassing the Windows online account restrictions, ... and I'm just sitting here, a UNIX fanatic, just wishing, praying I could write all this stuff into a script and just string together some commands to run each installation. Instead it's this gruelling horrible task that I have to repeat over, and over again. Shell scripts fix this. They just give you everything you need: success or fail state for any command, easy printing capabilities, early returns, and calling other smaller POSIX utilities on your system when you need to. If you're targetting a POSIX shell, you might as well also throw in POSIX tools like cat, grep, or make.

I just wanted this to be a little kick in the pants for people to try shell scripting. It's easy, it's fun... it's like writing Python. Loosey-goosey, but works everywhere. (And, I'm pretty sure POSIX shell scripts are interpreted faster than Python 3.) My shell scripts here and on Codeberg in various projects are rather simple, I barely ever use an if-else construction and just use stuff like &&, ||, exit 0, and rudimentary functions and I'm more than happy with the results. Give the next .sh file you see a look and see if you learn something.

June 30, 2026