A Web Service Written in Pure Bash.

Is it beer o’clock yet?

Henry Snopek
Jan 5, 2017 · 4 min read

At @carrot we build out many APIs using Go and Node some of which are hosted on DigitalOcean and take advantage of Docker containers, but we also use the Amazon Stack, like Lambda, S3, and Cloudfront with Apex & Serverless. We have many tools to help us startup projects, like Spike when developing static sites or ash-github when setting up a repository on Github. While working on ash-github I joked about how everything should be written in bash. The more my coworkers and I joked about it, the more the idea grew in my head and soon the idea came to fruition.

The Dirt

The service itself is currently running on a Ubuntu 16.10 droplet on DigitalOcean. To expose my service I needed to open a connection with the outside world and initially played with netcat as it’s preinstalled on most *nix machines. This task wasn’t familiar to me at all, but I couldn’t read the incoming request and I couldn’t handle two users connecting at the same time. I explored inetd which lacked of documentation beyond the man page. Continuing with my research I found xinetd which is a more secure version of inetd. I also found a lot more sufficient documentation and user guides on creating a service. After installing xinetd I began building a primitive version of my pure bash service called beeroclock.

xinetd man page

Code Digestion

When a request is made it is consumed, the headers are parsed until we find the a carriage return signaling that we’ve hit the body, and then properly assign each piece to a variable. In this case we only care about GET requests and if pathname is correct. The service responds to two paths and one query parameter.

# route based response
/ock — text/plain
/ock.html — text/html
/ock.json — application/json

# query param based response
/ock?type=plain — text/plain
/ock?type=html — text/html
/ock?type=json — application/json

# favicon
/favicon — Beer Emoji
/favicon.ico — Beer Emoji

If you request any other route than one listed above you’ll get redirected to /ock. You’ll also have seen that there’s three content-types: text/plain, text/html, and application/json. The logic for the routing and query parameter consumption was originally simple and purely used regular expressions, though the response time was sluggish. I created a performance script for regular expressions & conditionals and tested it out locally and on the server. There was a significant difference, if/else conditionals were ~52.7% faster than regular expressions! Because of this I refactored using conditionals, but sadly there’s no noticeable performance boost with only a 100–200 millisecond difference in the request time.

Bash Performance Test — Regex vs If/Else

The response itself is constructed using a handful of functions, a few of them are: beertime and respond. The beertime function handles the time calculations and message to be used in the body. The latter constructs and replies with the appropriate response while only consuming two parameters: content-type & body. To calculate your timezone, for proper beer consumption of course, I send a request to a separate service that contains the requestors IP Address which responds with your timezone. I then set the environment variable TZ in the subshell I spawn when executing beertime. The output from beertime is consumed by another function called respond which sets the headers and echoes the whole response back to the client.

To Recap…

Bash should probably remain a scripting language, but like any language we should explore and find ways to bend it until it breaks. I really enjoyed building beeroclock and always enjoy asking my co-workers what time it is. The source code can be found here hhsnopek/beeroclock and I welcome contributions to better the project — Cheers!

Hacker Noon is how hackers start their afternoons. We’re a part of the @AMI family. We are now accepting submissions and happy to discuss advertising & sponsorship opportunities.

If you enjoyed this story, we recommend reading our latest tech stories and trending tech stories. Until next time, don’t take the realities of the world for granted!



Sign up for Get Better Tech Emails via HackerNoon.com

By HackerNoon.com

how hackers start their afternoons. the real shit is on hackernoon.com. Take a look

By signing up, you will create a Medium account if you don’t already have one. Review our Privacy Policy for more information about our privacy practices.

Check your inbox
Medium sent you an email at to complete your subscription.

Henry Snopek

Written by

💻 Engineer & Coffee Lover ☕️


Elijah McClain, George Floyd, Eric Garner, Breonna Taylor, Ahmaud Arbery, Michael Brown, Oscar Grant, Atatiana Jefferson, Tamir Rice, Bettie Jones, Botham Jean

Henry Snopek

Written by

💻 Engineer & Coffee Lover ☕️


Elijah McClain, George Floyd, Eric Garner, Breonna Taylor, Ahmaud Arbery, Michael Brown, Oscar Grant, Atatiana Jefferson, Tamir Rice, Bettie Jones, Botham Jean

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store