Skip to main content

Bash Linting. Checking your scripts are nice and lint free

Continiuing on from my previous post on testing shell scripts with bats I have been looking for a linting solution for shell scripts. And I think I have found a nice one in shellcheck. Which is aviailble as both a website and a packge on debian.

It's really simple to run just give it your shell script as an argument and you get a nice set of comments on the style of your code. Here is the result of testing their test script.

#!/usr/bin/env bash
## Example of a broken script. Hit the Down Arrow button to ShellCheck it!
for f in $(ls *.m3u)
  grep -qi hq.*mp3 $f \
    && echo 'Playlist $f contains a HQ file in mp3 format'

Then run shellcheck

In line 3:
for f in $(ls *.m3u)
         ^-- SC2045: Iterating over ls output is fragile. Use globs.
              ^-- SC2035: Use ./*.m3u so names with dashes won't become options.

In line 5:
  grep -qi hq.*mp3 $f \
           ^-- SC2062: Quote the grep pattern so the shell won't interpret it.
                   ^-- SC2086: Double quote to prevent globbing and word splitting.

In line 6:
    && echo 'Playlist $f contains a HQ file in mp3 format'
            ^-- SC2016: Expressions don't expand in single quotes, use double quotes for that.

I have a simple makefile now that's just there mostly as a reminder of the testing that is aviailble for that script.

bats: *.bats
    bats *.bats

lint: your_script your_nextscript
    shellcheck your_script
    shellcheck your_nextscript

Next up is intergration with vim. I use the really nice syntastic vim plugin. Syntastic does automatic style checking on files as you save them and shows a set of errors. Installing it is simple. Install shellcheck, I use apt-get install shellcheck on Debian but you can use your favorite way on your OS. Then install the vim syntastic, again I use Vundle so adding Bundle scrooloose/syntastic to my .vimrc and then running BundleInstall in vim did the trick for me. Now when I write a shell script to disk vim will comment on my style.

Setting Soundcard names in Gnome

I have a couple of sound cards attached to my laptop at work and it gets confusing to know which one is which when they have names like "Analogue line out". So I set about changing them and struggled a bit in the process so I thought I would note it here for reference.

Gnome takes the name of the soundcards from pulseaudio. There does not seem to be a way to rename them directly in gnome but you can do it from the command line. The command pacmd list-sinks will give you a list of the devices that you have. Looking through that list at the 'name:' field are the identifiers that you can use. ( You can also use the ID but I am not sure how stable they are ) The man page for pulse-cli-syntax is the rather confusing location for the commands that you can give the pacmd command.

Now we know which card we want we can change the description property that Gnome uses with the following command. Note the extra quotes are required if your description has spaces in it.

update-sink-proplist alsa_output.usb-Burr-Brown_from_TI_USB_Audio_DAC-00-DAC.analog-stereo 'device.description="External Blue headphones"'

Then you can run the pacmd list-sinks command to check that works. At the gnome level nothing will have changed. So now you need to add this to your config file ~/.config/pulse/ which is just a list of pacmd commands to run on startup. You can now drop the extra single quotes as it does not need to be escaped for the shell prompt.

Update: You need to add the line below to your so that it knows about the default config. Pulseaudio only loads one config file by default so this just makes sure you get the default settings first.

.include /etc/pulse/

Now it just remains to get pulseaudio to re-read it's config in the usual unix way by giving it a HUP.

pkill -HUP pulseaudio

Listening to SSL with socat

I wanted to dump the headers for a http request over ssl today. Pulled out socat and this command and it seemed to work quite nicely.

socat OPENSSL-LISTEN:4433,cert=server.crt,key=server.key,verify=0 -

You will need to create server.crt and server.key and if you don't want the other end to complain then they should be a valid keypair.

Socat is a really nice tool that exposes the power of Unix sockets and allows you to connect anything together. In this case a tcp socket with ssl support and the standard out. But it could be a UDP port and a serial cable for all all socat cares. A really nice tool.

Flattr me