Skip to main content

Exploring CLI: Better Bash Scripts With Bashly Part 1

The main reason I prefer Unix/Linux over Windows operating systems is the terminal. Nix terminal shells just feel cleaner and organized to me than that of CMD or PowerShell. I won't claim to be an all knowing expert on the subject, I can only speak on what I've experienced, but the preference is 95% based on the feel of it overall. The Unix CLI philosophy and POSIX standards provide us with a powerful and versatile tool with simple commands that each do one thing and do it well. Spend some time typing out some PowerShell 'one-liners' then jump in a Nix terminal and I am willing to bet you will at least understand.

Bash has been around a long time with version 0.99 being released in 1989. It's mature, programmable and versatile. Bash is the default shell of many popular linux distributions and used to be the default for Mac 
OS before the switch to zsh. Some common commands we use are actually shell scripts (e.g gunzip, ldd and which). I am not a Bash programming expert, but I try. 

Some rules I keep in mind when tackling scripting are:
  • if I do something more than 3 times I should write a script. (popey says this)
  • a command should do one thing, and do it well.  (unix philosophy-ish)
When building websites, image resizing is tedious. Responsiveness has complicated things. Remember when you only viewed websites on one device? I do, I also remember when we didn't have websites at all. These days, thanks to HTML by Tim Berners Lee, not only can you view porn as fast as your connection, but you can view it in multiple ways on many devices. Anyway, I have decided I want scripts for doing a few different things. This article covers creating multiple sizes of an image to use as a srcset to demonstrate how I use Bashly to overcome my limited knowledge and experience.


Bashly itself is written in ruby and can be installed using gem.

Note:

If Ruby isn't installed on your computer consult the official documentation for instructions. MacOS comes with a version of Ruby installed but attempting to install using the system gem command will result in a persmissions error. To install a newer version of ruby locally so as not to interfere with the systems version I recommend using a tool version manager. Personally I use asdf.

Once Bashly installs successfully you should be able to start building your CLI.

Starting a project is simple and if you visit the Bashly home page, theres a cool animation that shows the steps.
  • create a directory for your project
  • cd into the directory
  • run 'bashly init' or 'bashly init --minimal'
These steps should leave you with a directory that looks like this:

|- myProject
   |- src
      |- bashly.yaml
      |- root_command.sh


The file 'bashly.yaml' is where the Bashly magic starts.  Here is the yaml for my srcset command:

A quick breakdown of what I have in there and why:
  • variables - I set some globals here when I started and had the functions split up into different scripts, but then didn't change it once I just put everything into the root_command script so my editor would stop complaining about undeclared variables. 
  • dependencies - this script requires imagemagick to be installed and placing this here inserts a check automatically so if you try to run the script on a system without imagemagick installed it errors out.
  • args - this of course is a file name. i did not add required to this because i do checking in the script and allow input from pipe (/dev/stdin).
Once the bashly.yaml is complete, you will find 'root_command.sh', also in the src directory. This is where you would put your main code. I'm guessing for larger more complex applications it would be ideal to have the common library functions split into separate files for organization and you can create support or this with the 'bashly add lib' command. This command creates a subdirectory named 'lib' in the src folder, and here you can create seperate files containing functions that can be accessed by any part of your code. I was being bugged by shellcheck in zed editor about undeclared variables and it was bothering me so I moved all my code to the root_command.sh file. This isn't a big deal because the code is pretty simple and most of the heavy lifting of creating and parsing the command line and using getopts is handled by bashly. In the end (at this point anyway) this is what my root_command.sh file looks like:


With those two files put together all I have to do is run 'bashly generate' from the root directory of the project and bashly puts everything together into one script named 'srcset' and makes it executable. Move that file into PATH and voila I have a custom command, srcset, that will make resizing my images for srcset as easy as 'srcset image.jpg'

Code for this project can be found on github here.

Comments, corrections, suggestions all welcome :).

ascii art: https://www.asciiart.eu/
ascii text: figlet
you suck at programming: https://ysap.sh/

Comments

Popular posts from this blog

2012 iMac Upgrade

I’ve always been fascinated by the longevity of Apple products. They build incredible machines, and unfortunately, Apple’s support lifecycle often leaves them abandoned – a growing mountain of e-waste. Recently, I was scrolling through the marketplace, and I spotted a treasure: a 2012 21.5” iMac for a ridiculously low $100. It was a gamble, a leap of faith, and frankly, I had no idea what I was getting into. I dove headfirst, did some quick research, and the result was...well, let’s just say it was an adventure. I’ll share the full story of my $100 Mac rescue – including the initial challenges, the surprising discoveries, and what I learned along the way. iMac 13,1 Specifications When introduced on October 23, 2012, this particular iMac came in three options: 2.7 GHz Core i5 (I5-3330S) Order: MD093LL/A  Model: A1418 (EMC 2544) RAM: 8 GB VRAM: 512 MB Storage: 1 TB HDD 2.9 GHz Core i5 (I5-3470S) Order: MD094LL/A Model: A1418 (EMC 2544) RAM: 8 GB VRAM: 512 MB Storage: 1 TB HDD 3.1 GHz...

Apple Magic Keyboard 2 Battery Replacement

Facebook Marketplace is a great way to get some good stuff super cheap. Sellers are often not very honest or not knowledgable about the items they have which can make it a little tricky to navigate. Sometimes, they are both of those things and even if someone is attempting to rip you off you can still come out on top with a little technical knowledge. Recently I found a listing for this Apple Magic Keyboard (lighting port) combo listed for $35. Well, as you can see in the image below this combo still sells on Amazon for $120+ used. The items on marketplace even came with the original packaging. I was skeptical, but even if only one of the pair worked I was coming out on top so I offered $25 and got it. The whole exchange was weird. I picked up the items and went straight home and put both on a charger for a while to see what I had. The mouse worked perfectly. The keyboard however, did not. One thing about the newer Apple Keyboards I can't stand is the absence of an indicator light ...

2022 M2 Macbook Air Screen Replacement

  At about six months of age, my son, Alex, was lying on the floor next to my wife, who was using her laptop. She had placed her phone down to speak with me, and in an instant, Alex reached over and pushed the lid closed, inadvertently cracking the screen where the phone rested. I experienced an immediate sense of dread. While I am adept at performing minor repairs myself, I lacked experience with M-series Macs and decided to seek professional assistance from Best Buy. Upon speaking with the Geek Squad via phone, they provided a quote of $120 for the repair and advised me to bring the device to their store. Upon arriving at Best Buy, I was required to pay a deposit before the device could be sent out for repair. However, I was informed that the actual repair cost would be significantly higher than the initial quote. Reluctantly, I agreed to send the device out, and upon receiving an official quote, I discovered that the total cost was approximately $800. At that time, we were able ...