A few months ago I was looking for an easy way to make my computer unusable for anyone who isn’t me. Petty, maybe, but I know I’m not the only person who hates it when people touch my stuff. It is also satisfying to watch someone grab my laptop without asking, only to have no idea how to use it.
After re-wiring some keyboard shortcuts, I wrote aliases to make bash commands do weird stuff. Like making
ls display the contents of the wrong directory or act like the user made a typo when they hadn’t. This became a week long project that morphed into a prank I could put on my friend’s computers too.
Version 0 was written in Python+Bash and aliased all common commands to a program that would add typos to a command before evaluating it. It was essentially its own command line utility. It was about 200 lines long, excluding installation instructions, documentation, and these guys:
from sys import argv
It worked — but it wasn’t a very good prank. The 30 line long README explained how to clone the repo, copy the contents to somewhere in $PATH, change some permissions around and other stuff you really shouldn’t be able to do on someone else’s machine.
200 lines is pretty excessive for a little program that just takes a string, flips two random letters and then evaluates the result. Plus, it used a shell script to install a Python script which was called by a different shell script. Lots of unnecessary stuff!
Learning Bash for Real
The core problem with my approach was the assumption that I had to use Python. Once I ditched my favorite programming language in favor of a pure Bash approach, all the pieces came together. Shell scripts can do so much more than I thought they could!
Here were some of my revelations:
I had installed programs before that required me to add a directory to my $PATH, but I hadn’t registered exactly what that meant. After this project, installing command line programs got less scary. My understanding of UNIX tripled that day. V0 made overzealous use of this feature and I got rid of it in V1.
The biggest problem with V0 was the installation. I had no idea you could just send the output of a
curl command to
source. Once I figured that out I decided the installation script had to be
source <(curl script.sh). That makes things faster, easier, and less intrusive! It also meant my Python script had to go.
Another thing I did not initially understand about Bash is how variables work. Since everything is a text stream, variables don’t have types. Because of this I ended up doing a lot of extra work slicing and reconstituting commands. Just using the full output stream saved me about 10 lines.
Refactoring V0 to V1
By the end I had replaced a 200 line project, with multiple files and complex installation instructions, to this 23 line file.
The final V1 is shorter than the README for V0! It can also be easily used with a single command:
source <(curl -s eepy.net/typo.sh)
Typing this command into my friend’s terminal downloads the little script and sends it to
source which acts as if I had typed all 23 lines and pressed enter. This re-aliases a bunch of common commands to a function called typoify which adds typos to the command you passed it, swaps two letters, and then evaluates the command as if you had typed it wrong.
Less code means less reading. The end result is much more manageable and legible. The program does what it is meant to do far more effectively than it did pre-refactor.
I have to explain why it took me a week to write 23 lines of code.
I learned a lot from this project. Bash is now an important (and powerful) part of my programming toolbox. It is worth learning the basics and paradigms of this language to use it properly.