DEV Community

Pipat Sampaokit
Pipat Sampaokit

Posted on

Shell Script Template

Record everything in a shell script

Usually when I work with source code in a software project, no matter it is Java, Python, or any other languages, there are some infrastructure set up tasks that need the use of shell scripting.

It is very useful to record EVERY shell commands that involve the source code. For example, when you initialize a NextJs project, you would write yarn create next-app your-app. It is not a waste of time to record this in a utility script so that you and your friend know EVERYTHING commands that involve the project.

#!/bin/bash

init_project() {
    yarn create next-app your-app
}
Enter fullscreen mode Exit fullscreen mode

Suppose you have a command to be used in CI/CD configuration tools such as Gitlab CI, you write all the core command in this shell script and have Gitlab CI invoke your script.

# In your utility.sh
build_and_deploy_to_k8s() {
    yarn build
    build_docker_image
    publish_docker_image
    deploy_to_k8s
}
Enter fullscreen mode Exit fullscreen mode
# In your .gitlab-ci.yml
deploy:
    stage: deploy
    script:
        - ./utility.sh build_and_deploy_to_k8s
Enter fullscreen mode Exit fullscreen mode

With this practice, you verbosely declare almost everything in the source code. The future you and your friends will share equal knowledge of what happens in the whole life cycle of the project and can investigate and reproduce any issue.

To do this, your utility.sh will need some common features:

  1. You can add a new group of commands in a bash function and invoke the function easily, like ./utility.sh your_new_function.
  2. You can add documentation to your commands so that they can be shown when the user executes the script with ./utility.sh help
  3. The ./utility.sh help command can list all the available commands and their documentation.
  4. You can add private commands that do not show to the user and cannot be invoked externally.
  5. The script can handle when the user enters an invalid or no command.
  6. The script has an easy error handling mechanism.
  7. The script is in compliance with shellcheck standard.

My template

I share my template that work for me in most case in my Github, please check it out.

Example Usage

$ ./example.sh

alert
    To print a normal message with a cute cow.

all_commands
    Show all available commands

error
    To print an error message with a cute cow, and then exit the script with non-zero exit code

ex_happy
    Test happy case

ex_oops
    What will happens when there is an error that your forgot to handle with && and ||

ex_public_command
    All function that starts with _ will now be listed and cannot be invoked externally.
 But you can still invoke the function inside the script itself.

ex_success_or_failure
    This example show you the error handling behavior.
 You can use || and && to handle in case your command fails.
 If a command in a pipe fails, all the pipe also fails

ex_unhappy
    Test the "error" command

greeting_n_times
    your documentation

help
    Show all available commands and their documentation

$ ./example.sh greeting_n_times

 ______________________
  < Missing 1st parameter for name of the person >
 ----------------------
        \   ^__^
         \  (xx)\_______
            (__)\       )\/
             U  ||----w |
                ||     ||

$ ./example.sh greeting_n_times John

 ______________________
  < Missing 2nd parameter for the number of time to say hello >
 ----------------------
        \   ^__^
         \  (xx)\_______
            (__)\       )\/
             U  ||----w |
                ||     ||


$ ./example.sh greeting_n_times John 3
Hello John
Hello John
Hello John
Enter fullscreen mode Exit fullscreen mode

Top comments (0)