Improving my bash Shell Scripting
4 min read
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.
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
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
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.
Bash Script to easy create or delete apache virtual hosts on ubuntu
Static analysis tool - ShellCheck
- In addition to the article by Nick Janetakis I linked above, I further read ShellCheck's README and David Jeddy's blog
- I installed the recommended VS Code extension for highlighting problems as I code.
- Happily I found that there's a GitHub Action for Shellcheck to lint for problems when I push changes to a branch.
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
mainvia Pull Requests)
- specifically use the Ubuntu 20.04 image (by choosing
runs-on: ubuntu-20.04rather than
- lint all branches except
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