Shell parameter expansion : default values for shell script parameters

When writing shell scripts, it’s often useful to accept some command line parameters.  It’s even more useful to have some defaults for those parameters.  Until now I’ve been using if statements to check if the parameter was empty, and if it was, to set it to the default value.  Something like this:

#!/bin/bash

DB_HOST=$1
DB_NAME=$2
DB_USER=$3
DB_PASS=$4

if [ -z "$DB_HOST" ]
then
    DB_HOST="localhost"
fi

if [ -z "$DB_NAME" ]
then
    DB_NAME="wordpress"
fi

if [ -z "$DB_USER" ]
then
    DB_USER="root"
fi

echo "Connecting to the database:"
echo "Host: $DB_HOST"
echo "Name: $DB_NAME"
echo "User: $DB_USER"
echo "Pass: $DB_PASS"

It turns out there is a much more elegant way to do this with shell parameter expansion.  Here is how it looks rewritten:

#!/bin/bash

DB_HOST=${1-localhost}
DB_NAME=${2-wordpress}
DB_USER=${3-root}
DB_PASS=$4

echo "Connecting to the database:"
echo "Host: $DB_HOST"
echo "Name: $DB_NAME"
echo "User: $DB_USER"
echo "Pass: $DB_PASS"

This is so much better. Not only the script itself is shorter, but it’s also much more obvious what is going on.  Copy-paste errors are much less likely to happen here too.

I wish I learned about this sooner.

How to Read and Improve the C.R.A.P Index of your code

crapclasscompletetest

Levi Hackwith has an excellent post explaining “How to Read and Improve the C.R.A.P Index of your code“:

The C.R.A.P. (Change Risk Analysis and Predictions) index is designed to analyze and predict the amount of effort, pain, and time required to maintain an existing body of code.

It iterates over the old bits of wisdom – write simpler code and cover it with unit tests – but it does so in a very simple and measurable way.

He also reminds us that:

…software metrics, in general, are just tools. No single metric can tell the whole story; it’s just one more data point. Metrics are meant to be used by developers, not the other way around – the metric should work for you, you should not have to work for the metric. Metrics should never be an end unto themselves. Metrics are meant to help you think, not to do the thinking for you. ~Alberto Savoia

Terminology – split screen terminal alternative to Terminator

terminology

If you are spending a lot of time in console, and have to manage multiple windows, there are a few options for you – screen, tmux, and, of course, Terminator.  Recently, I’ve come across one more – Terminology.

Terminology is a console with built-in window multiplexing.  It feels a bit more fancy than the options above and I enjoyed using it for about half a day.  From then on, the look, feel, and unfamiliar mouse and keyboard behavior threw me back into the Terminator window.  But f you were looking for an alternative to the well established options, here is one to try.

Robo – Modern Task Runner for PHP

robo

There is a whole lot of ways to build and deploy web applications these days.  I’ve done my own circle of trials and errors and have some very strong opinions on which ones are good, which ones are bad, and which ones are ugly.

My most recent discovery was Robo – a modern task runner for PHP.  I’ve been pushing it to one of those weekends, where I have nothing better to do, to trying it out.  And today I did.  Not just tried it out, but replaced a part of our infrastructure, which was previously running on Laravel Envoy.

Robo is very nice.  On one hand, it’s simple and straight forward and is very easy to get you started with.  On the other hand, it provides quite a bit of functionality to help you with the build and deploy process.  Here are some of the things that I love about it:

  • It’s PHP!  Which makes it perfect for PHP projects, the kind I’m dealing with most of my time.  No need to translate your PHP into XML (hey Phing), or into a weird rake/capistrano like syntax.
  • Instant support for command line arguments and their validation, help screens, ANSI colors, and the like.  Honestly, I don’t know why we are still fighting these things in 2016.
  • Transparency.  You install robo with composer, create your RoboFile.php, and you are done.  All public methods of the class in the RoboFile.php will be available as robo commands.  All parameters of public methods are populated by the command line arguments.  There is no black magic to it.  All that is executed is whatever you write.
  • Extensions (or Tasks and Stacks).  There are a few to utilize already (SSH, git, and more).  And it is trivial to write your own and share them with composer/Packagist.  That’s one of the things that is difficult with our current build setup based on phake (hence our phake-builder).

Things I don’t like (remember I have been using Robo for just about 3 minutes):

  • Logging.  While it’s trivial to add logs into the RoboFiles using your choice of the logging library (monolog is awesome), I haven’t found a way to get all the output after the command execution.  For now, I’ve wrapped the Robo run into a shell script, which collects all outputs and sends it by email into our deployment archives storage.
  • Remote power.  Robo has some very cool tasks and stacks for local work.  But I haven’t found a way to utilize them when using Robo’s SSH task.  This slightly spoils the clean remote commands with sprinkles of bash, which I would love to avoid.

Overall, it looks like a very nice and elegant system and I’ll probably be using it for much more.  Once I get a bit more comfortable with it, I will probably replace our phake-builder setup with Robo.

If you are looking for a good tool to use for your build and deploy needs, give it a try.  You’ll probably like it a lot.

Documenter v2

I came across a very handy tool for writing quick and simple documentation – Documenter v2.

documenter

It provides a quick and simple web interface to handle document meta information (titles, subtitles, author, created and updated dates, etc), sections, styles, extra buttons, and more.  You can also download and save the results, as well as continue where you left off later.