Testing Bash with Bats

Spectacled Fruit Bat by Shek Graham

Spectacled Fruit Bat by Shek Graham

I quite like unit tests. They give you that quick feedback that things are going to be okay. I can write a test watch it fail. Write some code and watch it fail also. Then learn very quickly what I have done wrong.

At some point last year I read the Clean Code book by Rober C Martin and it opened up to me a lot of the ideas about testing and code that I had not really got to grips with at the time. Martin takes you through the reasoning and process for producing code that, in a years time, you might want to actually look at and feel comfortable editing.

What has this go to do with bash and bats? Well we have been adding more tests to our puppet code and it came time to write a bit of bash for moving some files around. I thought there must be a simple way to check some of this and sure enought that is where bats comes in.

bats is a testing framework for bash scripts. I know it sounds crazy but it really does work. If you start applying some of the lessons from clean code and spliting your work into functions with local varaiables it soon becomes easier to test. You can, as ever, take things too far but this does at least allow you to test a lot of your logic before you roll it out. With the added benifit of makeing the code a little more readable.

I found this blog post by Spike cleared up some of the questions I had about testing functions as well. http://blog.spike.cx/post/60548255435/testing-bash-scripts-with-bats

Some other useful things are the google shell style guide and shUnit2 which I have yet to look at. The Defensive Shell Guide by Kfir Lavi and Better Bash Scripting in 15 Minutes by Robert Muth are also good.

Using the ACS ACR122 NFC card reader under linux

If you are seeing some errors in the logs like the ones below:

pcscd[4489]: 58837251 ccid_usb.c:645:OpenUSBByName() Can't claim interface 001/110: Device or resource busy
pcscd[4489]: 00040743 ifdhandler.c:118:IFDHCreateChannelByName() failed
pcscd[4489]: 00000030 readerfactory.c:1043:RFInitializeReader() Open Port 0x200000 Failed (usb:072f/2200:libudev:0:/dev/bus/usb/001/110)
pcscd[4489]: 00000008 readerfactory.c:335:RFAddReader() ACS ACR122U init failed.

You need to prevent the kenel nfc drivers loading so add the following lines to /etc/modprobe.d/rfid-blacklist.conf

blacklist pn533
blacklist nfc

as suggested here: http://maciaszek.net/26522/rfid-reader-mit-debian/

Then remove those modules with modprobe -r pn533 nfc

Then install some packages

apt-get install libpcsclite1 pcsc-tools pcscd

Then run:


You should get some output similar to the stuff below.

PC/SC device scanner
V 1.4.23 (c) 2001-2011, Ludovic Rousseau <ludovic.rousseau@free.fr>
Compiled with PC/SC lite version: 1.8.11
Using reader plug'n play mechanism
Scanning present readers...
0: ACS ACR122U 00 00

Thu Jan 22 23:00:58 2015
Reader 0: ACS ACR122U 00 00
  Card state: Card removed,

Thu Jan 22 23:01:06 2015
Reader 0: ACS ACR122U 00 00
  Card state: Card inserted,
  ATR: 3B 8F 81 01 80 4F 0C A0 00 00 04 06 03 00 01 00 00 00 00 6A

ATR: 3B 8F 81 01 80 4F 0C A0 00 00 04 06 03 00 01 00 00 00 00 6A
+ TS = 3B --> Direct Convention
+ T0 = 8F, Y(1): 1000, K: 15 (historical bytes)
  TD(1) = 80 --> Y(i+1) = 1000, Protocol T = 0
  TD(2) = 01 --> Y(i+1) = 0000, Protocol T = 1
+ Historical bytes: 80 4F 0C A0 00 00 04 06 03 00 01 00 00 00 00
  Category indicator byte: 80 (compact TLV data object)
    Tag: 4, len: F (initial access data)
      Initial access data: 0C A0 00 00 04 06 03 00 01 00 00 00 00
+ TCK = 6A (correct checksum)

Possibly identified card (using /usr/share/pcsc/smartcard_list.txt):
3B 8F 81 01 80 4F 0C A0 00 00 03 06 04 00 01 00 00 00 00 6A
3B 8F 81 01 80 4F 0C A0 00 00 03 06 .. 00 01 00 00 00 00 ..
    Mifare Standard 1K (as per PCSC std part3)
3B 8F 81 01 80 4F 0C A0 00 00 03 06 04 00 01 00 00 00 00 6A
3B 8F 81 01 80 4F 0C A0 00 00 03 06 04 .. .. 00 00 00 00 ..
    RFID - ISO 14443 Type A Part 3 (as per PCSC std part3)
3B 8F 81 01 80 4F 0C A0 00 00 03 06 04 00 01 00 00 00 00 6A
    Philips MIFARE Standard (1 Kbytes EEPROM)
    RFID - ISO 14443 Type A - Transport for London Oyster
    ACOS5/1k Mirfare
    RFID - ISO 14443 Type A - NXP Mifare card with 1k EEPROM
    vivotech ViVOcard Contactless Test Card
    Bangkok BTS Sky SmartPass

More next time.

Scrolling text on a rainboduino

Spent a little time last night at Hackspace writing some basic code to scroll some text across a rainbowduino.

I use arduino-mk ( pacakge available on debian ) so here is the basic makefile to build it.

BOARD_TAG    = atmega328
ARDUINO_LIBS = Rainbowduino
ARDUINO_DIR   = /usr/share/arduino
ARDMK_DIR     = /usr/share/arduino

include /usr/share/arduino/Arduino.mk
 Rainbowduino v3.0

 Scrolling text


#include <Rainbowduino.h>

String message = "John is ace!";

void setup()

unsigned char x,y,z;

void scroll_text(String msg)
    int len = msg.length();
    const int kern = 6;
    byte msg_b[len+1];
    msg.getBytes(msg_b, len+1);

    for (int i = 0; i <= len * kern ; i++) {
        for (int b = 0 ; b < len ; b++) {
            if ((b * kern) > ( i - kern) && (b * kern) < (i + kern) ) {
                Rb.drawChar(msg_b[b],- i + (b * kern),1,random(0xFFFFFF));

void loop()



Internet Notes from about week 02

A new year and a new blog post....

Tech news

All things python: http://pycoders.com/2014/ - This is a list of the best of the pycoders weekly from last year. Some really great posts in there.

Testing our puppet code has become a big thing for us now. More and more of our code has spec tests using rspec-puppet and puppetlabs-rspec-helper. We are also starting to experiment with beaker that server-spec that allow us to boot up a Virtual Machine(VM) and run tests against an applied manifests. Which then leads me on to a interesting project called test-kitchen which was created to do a similar thing for Chef recipies. http://pocket.co/s_5Sx is an interesting post about how to use test-kitchen and docker to do the same for puppet.

Clearing out

Keeping up with my clearing up and with a bit of a new year burst of enthusiasm I have binned my old CD player that I brought at University and no longer works feels such a shame to take it to the tip. Also selling DVD player, AV Amp, Huge speakers on Gumtree. Now I just have a nice stereo amp and small speakers hooked up to a squeezebox for music and radio. Then an Kodi ( was XBMC ) box for watching Youtube and movies etc. All neat and tidy. Next up is sorting the Minidisc collection and getting rid of that too. Everything must go.

I got given a vice for Christmas, no not that sort, a woodworking vice. So now I just need to build a bench to attach it too. So look out for some more woodworking stuff.

Do no evil

I am going to try going back to this blog for some online stuff. I am starting to worry about my dependence on Google. I have been looking at owncloud and I kickstarted ( is that a word now? ) the http://sandstorm.io/ project and the Mozilla Matchstick last year as well.

Stuff from the internet

Bikes and that

http://www.thediscerningcyclist.co.uk/2014/09/quoc-pham-the-derby-review/ - Some really nice cycling shoes. I don't have clipless pedals but if I did these would be the shoes for me. Oh and their boots in the winter.


https://medium.com/@lucperkins/web-development-in-c-crazy-or-crazy-like-a-fox-ff723209f8f5 - It may seem mad but why not write your next web application in C? Some good tips if you do and a couple of interesting libraries even if you don't.

https://vimeo.com/71278954 - The future of programming circa 1974, given in a talk in 2014. TL;DW we are still programming like it's 1974.


http://blog.petersobot.com/pipes-and-filters - A really simple introduction to what is going on in a unix pipe. Good to remind yourself of the basics sometimes.

http://youtu.be/mgcJPREl3CU?list=PLDGkOdUX1Ujo3wHw9-z5Vo12YLqXRjzg2 - Some good videos showing you how to driver Grafana which is turning out to be a really smart front end to graphite.


http://www.rayjardine.com/papers/why-sew/index.htm - I brougt a broken sewing machine of ebay based on this post. ( Why do I insist on shaving the yak first every time?)

https://woodworkingmasterclasses.com/ - I have been watching hours or Paul Sellers videos. He has such a great presenting style. Just watching him work is a pleasure. It's all hand tools as well so it a much more relaxed pace. I am seriously concierding treating myself to one of his courses.

Everybody needs a cake flag

Email can be very distracting and so we all try different techniques to limit those distractions. I am fairly settled now on an Inbox Zero type of approach. I don't always have me inbox open, I don't have any alerts or notifications and I read and file my mail at intervals during the day. It works for me for the most part and I don't find the nervous tick of checking my email every time my mind wanders to be too distracting.

All good, you may think. Lots of unbroken time for working on the real work but this does have one major fault. Less cake! Every so often we get an email that alerts us to the presense of cake in the building. These need an instant response. And this is where the cake flag comes in. Every time I get an email that is related to cake a Heath Robinson setup of filters, process and electronics kicks in a the cake flag is raised. We can then check our email and run to where the cake is. No more missed cake.

How does it work? There is a filter in gmail that identifies the important messages. (I know what you are thinking and unless you bring me cake an intentional false alarm means your email goes to the bottom of the long grass pile). This sends the email to another gmail account that I have registered for this porpose so that I don't have to store my main account details. I then have a small Python script that registers checks that gmail account for new mail. This then tells the Arduino on my desk, that is there to monitor if my chilli plant needs watering, that there is cake. The Arduino then prints a message on the LCD: ***CAKE*** and raised the cake flag by means of a servo. And everybody runs for cake.

There have been some improvements along the way. I have added a web api so people can reset the cake flag if I am not there. Later I noticed that we missed a call for Champagne this bug has now been fixed.

Trying out Atom as an editor

I use Vim as my everyday editor mostly because it's available on all the systems that I have ever administored. Once you get used to a modal editor though it gets very annoying trying to use anything else.

I have been trying to ignore the buzz around the Atom editor from GitHub for a while now but had to give in recently. So I downloaded, compiled and installed it. That was pretty painless and it makes a nice .deb by default so I can install it cleanly. Good so far.

Next up was to launch it and have a play. Wow! it's quick. I assumed it would be a fairly beefy startup and while nothing could be as slow as Eclipse I thought it might be of that order but no it's pretty lean.

Editing in it. Well it's pretty slick. There are a million new keyboard shortcuts and I think a lot of them are mac based so it's all a bit weird.

Making it easier with the vim plugin. I am not a great fan of plugins that make something behave like something else as it often makes things not work how they expect. In this case I don't think I can go back to a non modal editor.

It looks nicer. I can't deny that the smoothness of the interface and the cleanness of the style looks nicer than the harsh terminal interface. Things like having a builtin preview for Markdown or RST is nice.

In conclusion I might give this a bit of a go.