slothi-bash

Once upon a time in a bustling tech company, there lived a clever, albeit slightly lazy, developer named Slothi.


Known for his knack for finding shortcuts, Slothi was assigned the task of creating a standardized bash script structure for the organization.


With a deep sigh and a sip of their fifth coffee of the day, Slothi set out on his scripting quest.

The Journey

Slothi’s assignment was to create a bash script structure that would be versatile, easy to use, and could become a template for all future scripts in the company.


The script needed to handle arguments, provide help and usage information, and include robust error handling. It sounded daunting, but Slothi knew just how to approach it.


As Slothi delved into the task, he realized the complexity of creating a script that could be both flexible and user-friendly.


“Why do all great adventures come with equally great challenges?” he mused. But with determination, Slothi began drafting his plan.


Slothi’s needed his template to cover a few areas:

  • Handling variables, constants and setting up default values and placeholders.
  • Handling different arguments and providing helpful messages.
  • Making sure anyone using the script could easily understand how to do so.
  • Incorporating clear error messages, logging and debug mode to troubleshoot issues.
  • Handling the main script logic.


Variables and Constants

    DEFAULT_VALUE="some value"

Argument Parsing

    while (($#)); do
        case "$1" in
            --required-param ) required_param=${2}; shift 2;;
            --optional_param ) optional_param=${2}; shift 2;;
            --debug ) debug=1; shift 1;;
            --help ) help; exit 0;;
            --usage ) usage; exit 0;;
            * ) usage; error "unknown argument"; exit 1;;
        esac
    done

Help and Usage Functions

   function help {
      echo "
        NAME
          $0 - short explanation what the script does

        SYNOPSIS
          $0 [--required-param  <value>] [--optional_param <value>]
                   [--debug] [--help] [--usage]
        $(arguments)
      "
   }
   
   function usage {
      echo " $(help)

        DESCRIPTION
            Sample script that shows template to be used for bashing.

            In this section we should explain what the script does.

            DEBUG

            A debug flag has been provided to enable script execution in debug mode. This is done
            to allow troubleshooting in case of issues with the script.

        EXIT STATUS CODES:
            Exit code 0  Success.

            Exit code 1  General errors, Miscellaneous errors, such as 'divide by zero'
                         and other impermissible operations.

            Exit code 2  Misuse of script operations. Missing keyword, argument, or permission problem.

            Exit code 3  General issues. Missing artifacts, files, project, or failure to retrieve a project.

            Exit code ?  Non-zero exit status returned. Command failed to execute.
      "
    }

Error Handling Debugging and Logging

    attention() {
        echo -e "\e[31m$(date "+%Y-%m-%d %H:%M:%S") - ATTENTION: ${1}\e[0m"
    }
    
    note() {
        echo -e "\e[33m$(date "+%Y-%m-%d %H:%M:%S") - NOTE: ${1}\e[0m"
    }
    
    info() {
        echo -e "\e[32m$(date "+%Y-%m-%d %H:%M:%S") - INFO: ${1}\e[0m"
    }

    error() {
        echo -e "\e[31m$(date "+%Y-%m-%d %H:%M:%S") - ERROR: ${1}\e[0m"
    }

    if [[ ${debug} ]] ; then
        echo "debug mode activated"
        set   -x
    fi

The Template

#!/usr/bin/env bash

# ----- Variables -----
DEFAULT_VALUE="some value"

# ----- Functions -----

function arguments {
    echo "
        ARGUMENTS:
                        --required-param      Required
                                              Show case for a required parameter. Here we should explain the usage of the parameter
        
                        --optional_param      Optional, Default: $DEFAULT_VALUE
                                              Show case for a optional parameter. Here we should explain the usage of the parameter
        
                        --debug               Optional.
                                              Enables debug mode.
        
                        --help                Prints out help.
        
                        --usage               Prints out help.
    "
}

function help {
    echo "
        NAME
            $0 - short explanation what the script does
    
            SYNOPSIS
                $0 [--required-param  <value>] [--optional_param <value>]
                   [--debug] [--help] [--usage]
            $(arguments)
    "
}

function usage {
    echo " $(help)
    
            DESCRIPTION
                Sample script that shows template to be used for bashing.
    
                In this section we should explain what the script does.
    
                DEBUG
    
                A debug flag has been provided to enable script execution in debug mode. This is done
                to allow troubleshooting in case of issues with the script.
    
            EXIT STATUS CODES:
                Exit code 0  Success.
    
                Exit code 1  General errors, Miscellaneous errors, such as 'divide by zero'
                             and other impermissible operations.
    
                Exit code 2  Misuse of script operations. Missing keyword, argument, or permission problem.
    
                Exit code 3  General issues. Missing artifacts, files, project, or failure to retrieve a project.
    
                Exit code ?  Non-zero exit status returned. Command failed to execute.
    "
}

# https://misc.flogisoft.com/bash/tip_colors_and_formatting
error() {
    echo -e "\e[31m$(date "+%Y-%m-%d %H:%M:%S") - ERROR: ${1}\e[0m"
}

attention() {
    echo -e "\e[31m$(date "+%Y-%m-%d %H:%M:%S") - ATTENTION: ${1}\e[0m"
}

note() {
    echo -e "\e[33m$(date "+%Y-%m-%d %H:%M:%S") - NOTE: ${1}\e[0m"
}

info() {
    echo -e "\e[32m$(date "+%Y-%m-%d %H:%M:%S") - INFO: ${1}\e[0m"
}

some_function() {
    local _param=$1 

    info "beginning execution of function with ${_param}"
    # TODO: Add logic here
    info "completed execution of function with ${_param}"
}

# ----- Main -----

if [[ $# -eq 0 ]]; then
    usage; error "expects arguments"; exit 1;
fi

# argument parsing
while (($#)); do
    case "$1" in
        --required-param      ) required_param=${2};                     shift 2;;
        --optional_param      ) optional_param=${2};                     shift 2;;
        --debug               ) debug=1;                                 shift 1;;
        --help                ) help;                                    exit 0;;
        --usage               ) usage;                                   exit 0;;
        *                     ) usage; error "unknown argument";         exit 1;;
    esac
done

if [[ ${debug} ]] ; then
    echo "debug mode activated"
    set -x
fi

if [[ -z ${required_param} ]]; then
    error "argument --required-param is required";
    exit 2;
fi

if [[ -z ${optional_param} ]]; then
    warn "argument --optional-param not provided. default: '${DEFAULT_VALUE}'";
    optional_param=${DEFAULT_VALUE}
fi

# ----- Script logic ----

some_function "${required_param}"

exit 0


Bash Script Adventures Source Code


Slothi’s journey was one of creativity, problem-solving, and a bit of procrastination, but in the end, he succeeded. The organization now had a standardized, user-friendly bash script template that could be used across various projects, making everyone’s lives a little easier.


And so, Slothi earned not only a well-deserved break but also the admiration of his peers. With a final sip of coffee, Slothi leaned back and whispered, “Bash scripting, conquered.”