Improving my bash Shell Scripting

Although I've used Linux since 2003, and done some scripting over the years - usually to automate a task, I hadn't made a concerted effort to improve my coding.

I really rate Nick Janetakis and saw he had a post on quoting variables in bash which kicked off my interest again, and led to "better" style as a wrote a script to bootstrap a LAMP server from scratch, on Ubuntu. Although the eventual plan is to use something like Ansible, I wanted to first prove I could install it with minimal "magic", and so that meant a shell script.

A video-based course

A year earlier I'd watched sections of the Udemy course Bash Scripting and Shell Programming (Linux Command Line) by Jason Cannon. This time I watched the whole course again, usually in the early mornings with a cup of coffee. The videos are very well-shot, and are watchable even on a tablet screen.

A book

I often pair video-based learning with books, to cement my knowledge, and read the Packt book Mastering Linux Shell Scripting by Andrew Mallett, although I read this on O'Reilly Learning

Style guide

Google's Shell Style Guide seemed opionated but helpful

Boilerplates and frameworks

I ended up finding Bash 3 boilerplate the most useful

Inspiration from other projects

  • Centminmod

    Centmin Mod LEMP stack auto installer for an optimized Nginx, MariaDB, PHP-FPM & CSF Firewall stack for CentOS 6 & 7 developed by George Liu (eva2000). Nginx & PHP version management, adding Nginx vhost sites and Wordpress auto installer with Wordpress caching via a shell menu based.

  • RoverWire/virtualhost

    Bash Script to easy create or delete apache virtual hosts on ubuntu

Static analysis tool - ShellCheck

Create a GitHub workflow to lint with ShellCheck

  • In VSCode, add .github/workflows/lint.yml, and adapt the example from GitHub Action for Shellcheck, because we want to:
    • lint all branches except main (we want to protect the main branch, and ensure we only merge into main via Pull Requests)
    • specifically use the Ubuntu 20.04 image (by choosing runs-on: ubuntu-20.04 rather than runs-on: ubuntu-latest)
name: Lint

on:
  push:
    branches:
      - '**'
      - '!main'

jobs:
  shellcheck:
    name: Shellcheck
    runs-on: ubuntu-20.04
    steps:
    - uses: actions/checkout@v2
    - name: Run ShellCheck
      uses: ludeeus/action-shellcheck@master

This runs a workflow of two actions

  • checks out the code
  • runs shellcheck against matching files
git add .github/
git commit -m "Add linting workflow"
git push --set-upstream origin add-linting-workflow