Why Linux?

Published: 2015-01-11
Tagged: linux

Freedom. That's what I feel when I have to get shit done on Linux. I can change anything I want, given that I know the right commands. There's no one telling me that something is bad design, no one making a choice for me about how something is to be done. I haven't had someone make breaking changes in something that I work with everyday. There's no hiding anything - not behind fancy GUIs or proprietary file formats.

What is more, the system is more or less self-contained. Quite often all you need to solve a problem are tools that are installed by default in almost every distribution. If you do need a more specialized tool, your package manager will deliver it to you fast and free of charge.

Trust. This level of fine grained control brings security. No system can be fully secure, but Linux makes it harder to be insecure. Small attack area and pretty safe defaults make me always think twice before using my other system to check my bank account - what if something installed itself during a drive-by? Add to that the fact that the community is open and that updates are rolled out fast and nothing is kept a secret in order to protect the brand or increase shareholder value or any other complete fucking bullshit.

Now, not everything is sunshine and rainbows. Sometimes you just can't find the right line in the right config to edit. Sometimes you don't know why module X i being loaded instead of module Y or why that thing you disabled is back after an upgrade. Sure, you get to the bottom of that, but that'll eat 6 hours you'd rather be enjoying a nice stroll. I put off repairing my raspberry pi for a week because I couldn't invest that time.

It helps that you'll never be put on hold for 30 minutes while listening to madness inducing jingles on the phone, only to be disconnected. You can be sure you'll find some posts from 2006 about your problem with ten different answers, two of which work for you. That and you can always find help on IRC. Having problems with NTP? Just pop into #ntp on freenode and be problem-free once again.

Most importantly, I program every day. I deal with lines of text day in and day out. Text doesn't need too much GUI bells and whistles. Hell, it doesn't need a mouse too much. Well, just so happens that text is what Linux is all about. Bash isnt just a command line, it's also an interpreter with its own language so you can program while you program, dawg. Every single interaction with your tools can be done through text. There are some powerful text editors that are the icing on the cake. There is no difference between editing your program and editing your environment. Hell, there's no difference if you're doing it over a network, except that Vim doesn't have your theme. Every step towards getting shit done on Linux is a single smooth flow.

The above sums up my thoughts. If curiosity has gotten the better of you, continue onwards, brave soul.

The Ride Never Ends

The utilities found in Linux are small and therefore easy to compose, using things such as pipes, into larger units of logic. Since it all happens in the shell, you can put that logic in a simple shell script. Now you avoid having to type it all out and you can very easily hook it up to other utilities such a cron to run at specific time intervals. You can easily set up a script that ssh's into another machine, pulls down the database, and archives it on your machine (or any other machine). Setting this up takes minutes and doesn't require 3rd party tools and it's pretty much the same across any other *nix you might happen to work with now or in the future.

Going further, most everything in the system is a text file. You don't need special utilities to configure most applications. Any old text editor will do. You can do it from the terminal, which means no matter what *nix box your using, it'll be the same. You can also use the above mentioned utilities to help you manage the configuration files too. If you're looking for a setting, but don't know which file it might be in, just grep it.

One more step. You can access the source code of most everything you work with, even if you got it precompiled. Having a problem with a library? Just find the repository online and you've got a good chance of at least understanding where your problem is coming from. This doesn't apply just to the high level tools you're working with (Rails, Django, etc. in my case) but to the low level stuff as well. Your wifi drivers not allowing you to change channels while in monitor mode? Just download the right code, apply a patch (a text file in itself) using the aptly named patch utility, then make && make install. Done.

Do One Thing and Do It Well

This is one of those ideas that sits awkwardly in a corner and nobody notices it until it turns out it's running the whole show. Most Linux utilities are tiny programs that do only one thing. Examples here include utilities such as cat, grep, sed, tail, tar, watch, and many, many others. cat simply prints the contents of a file into stdout. grep searches for strings in files, allowing the use of regexp to that end. tail prints the last few lines to stdout. It can also continuously print new additions to the file, which makes it perfect for watching log files. tar takes care of archiving files as well as compressing/decompressing them. watch executes a command every n seconds, printing its output to stdout. sed edits streams on the fly.

Real life examples:

Ever had a csv file that listed numbers with comma separated colums (ie. 1,000,000.00)? Your American-locale-configured spreadsheet software might not play well with that. Search and replace? Might mess up the columns. Manually? All 5000 columns? Just do a sed -ir 's/([0-9]+),([0-9]{3})/\1\2/g' pesky.csv. Done.

Ever had to debug why gulp-sass wasn't outputting anything? You can use gulpjs to run the task every time you change the file, but how can you quickly check if whatever you tried actually worked? Just set a `watch -n3 -d 'ls -la | grep app.css'. It'll run that command every 5 seconds and highlight any changes in the output. File size not changing? Your fix ain't working. Your feedback loop is shortened to a max of 3 seconds and required no keystrokes. And it takes all of 5 seconds to set it up.

I could keep doing this forever, but lets head on over to...

Composability

Building on the last point, the real power of all those small utilities is that you can compose them. I kinda did that in the watch example where I also used grep to filter out unwanted stuff. The humble | is a powerful feature that allows you to redirect output streams into other applications. You can glue together as many commands with this as you need.

This power is enhanced even more with the awesome xargs utility, which invokes a command for every line of input it gets. Imagine executing a sed command for every line of the ls command. Add to that grep: ls | grep ... | sed and you have a quick way to edit a bunch of files real quick. Like 15 seconds max to think up a string for grep and a regexp for sed.

The icing on the cake? The tee utility. It simple takes whatever it is fed and writes it both a file and to stdout. Drop this into your series of pipes to get parts of the end product written to files.

I'll give you a minute to let all that sink in. Can you feel it? Can you feel it, punk?!

Ever had a server under a small DDoS attack and wanted to do something right now? Find a pattern in the server logs ie. a common user agent string. Feed the logs to grep to extract those lines, then feed grep's output to awk to put the ip address part of each line into an associative array and then feed the keys of that array into sed to prepend 'deny' and append ';' and write that all out into a file. Include that file in your nginx config, reload it, and enjoy blocking 20000 zombie computers. 3 minutes in total.

You can use the find utility to both find files with a specific name and execute a command on each file that matches the criteria. Sed is a natural candidate for this. Makes it super easy to update a bunch of source code when you find you have a name conflict somewhere.

Finally, since all these commands are part of a scripting language, throw them all in a script and automate all your troubles away. I'm about to set up a way for my raspberry pi to check its file systems itself. First it'll create a drive in the RAM, then copy itself into that drive, finally hand over control to that ephemeral copy and unmount the drive it was just running on to do a file system check. I don't know if that'll work, but if it doesn't there's a thousand other things I can try.

To be continued?

Hi, I'm Matt.

This blog is an unordered set of thoughts extracted from the mind of a software developer.