Shell Scripting Templates and Utilities
A collection of shell scripting utilities and templates used to ease the creation of BASH scripts. BATS provides unit testing capabilities. All tests are in the tests/ repo.
Bash Script Template Usage
To create a new script, copy scriptTemplate.sh to a new file and make it executable chmod 755 [newscript].sh. Place your custom script logic within the _mainScript_ function at the top of the script.
Script Template Usage
Default flags included in the base template are:
-h: Prints the contents of the_usage_function. Edit the text in that function to provide help-l [level]: Log level of the script. One of:FATAL,ERROR,WARN,INFO,DEBUG,ALL,OFF(Default is 'ERROR')-n: Dryrun, sets$DRYRUNtotrueallowing you to write functions that will work non-destructively using the_execute_function-v: Sets$VERBOSEtotrueand prints all debug messages to stdout-q: Runs in quiet mode, suppressing all output to stdout. Will still write to log files--force: If using the_seekConfirmation_utility function, this skips all user interaction. ImpliedYesto all confirmations.
You can add custom script options and flags to the _parseOptions_ function.
Script Template Functions
scriptTemplate.sh includes some helper functions to perform common tasks.
_alert_Provides alerting and logging functionality. See notes below._trapCleanup_Cleans up files on error_makeTempDir_Creates a temp directory to house temporary files_acquireScriptLock_Acquires script lock to avoid race conditions on files_functionStack_Prints the function stack in use to aid debugging_parseOptions_Parse options and take user input (-a,--some-flag, and--some-file [filename]supported)_usage_Prints help text when-hpassed_safeExit_Used to exit gracefully, cleaning up all temporary files etc.
Script Initialization
The bottom of the script template file contains a block which initializes the script. Comment, uncomment, or change the settings here for your needs
trap '_trapCleanup_ ${LINENO} ${BASH_LINENO} "${BASH_COMMAND}" "${FUNCNAME[*]}" "${0}" "${BASH_SOURCE[0]}"' \
EXIT INT TERM SIGINT SIGQUIT
set -o errtrace # Trap errors in subshells and functions
set -o errexit # Exit on error. Append '||true' if you expect an error
set -o pipefail # Use last non-zero exit code in a pipeline
# shopt -s nullglob globstar # Make `for f in *.txt` work when `*.txt` matches zero files
IFS=$' \n\t' # Set IFS to preferred implementation
# set -o xtrace # Run in debug mode
set -o nounset # Disallow expansion of unset variables
# [[ $# -eq 0 ]] && _parseOptions_ "-h" # Force arguments when invoking the script
_parseOptions_ "$@" # Parse arguments passed to script
# _makeTempDir_ "$(basename "$0")" # Create a temp directory '$tmpDir'
# _acquireScriptLock_ # Acquire script lock
_mainScript_ # Run the main logic script
_safeExit_ # Exit cleanly
Utility Files
The files within utilities/ contain BASH functions which can be used in your scripts. Each included function includes detailed usage information. Read the code for instructions.
Including Utility Functions
Within the utilities folder are many BASH functions meant to ease development of more complicated scripts. These can be included in the template in two ways.
1. Copy and Paste
You can copy any complete function from the Utilities and place it into your script. Copy it beneath the end of _mainscript_()
2. Source entire utility files
You can source entire utility files by pasting the following snippet into your script beneath _mainScript_(). Be sure to replace [PATH_TO] with the full path to this repository.
_sourceHelperFiles_() {
# DESC: Sources script helper files.
local filesToSource
local sourceFile
filesToSource=(
"[PATH_TO]/shell-scripting-templates/utilities/baseHelpers.bash"
"[PATH_TO]/shell-scripting-templates/utilities/arrays.bash"
"[PATH_TO]/shell-scripting-templates/utilities/files.bash"
"[PATH_TO]/shell-scripting-templates/utilities/macOS.bash"
"[PATH_TO]/shell-scripting-templates/utilities/numbers.bash"
"[PATH_TO]/shell-scripting-templates/utilities/services.bash"
"[PATH_TO]/shell-scripting-templates/utilities/textProcessing.bash"
"[PATH_TO]/shell-scripting-templates/utilities/dates.bash"
)
for sourceFile in "${filesToSource[@]}"; do
[ ! -f "${sourceFile}" ] \
&& {
echo "error: Can not find sourcefile '${sourceFile}'."
echo "exiting..."
exit 1
}
source "${sourceFile}"
done
}
_sourceHelperFiles_
alerts.bash
Basic alerting and setting colors functions (included in scriptTemplate.sh by default). Print messages to stdout and to a user specified logfile using the following functions.
debug "some text" # Printed only when in Verbose mode
info "some text" # Basic informational messages
notice "some text" # Messages which should be read. Brighter than 'info'
warning "some text" # Non-critical warnings
error "some text" # Error state warnings. (Does not stop the script)
fatal "some text" # Fatal errors. Exits the script
success "some text" # Prints a success message
header "some text" # Prints a header element
arrays.bash
Common functions for working with BASH arrays.
_inArray_Determine if a value is in an array_join_Joins items together with a user specified separator_setdiff_Return items that exist in ARRAY1 that are do not exist in ARRAY2_removeDupes_Removes duplicate array elements_randomArrayElement_Selects a random item from an array
baseHelpers.bash
Commonly used functions in many scripts
_execute_Executes commands with safety and logging options. RespectsDRYRUNandVERBOSEflags._findBaseDir_Locates the real directory of the script being run. Similar to GNU readlink -n_checkBinary_Check if a binary exists in the search PATH_haveFunction_Tests if a function exists_pauseScript_Pause a script at any point and continue after user input_progressBar_Prints a progress bar within a for/while loop_rootAvailable_Validate we have superuser access as root (via sudo if requested)_runAsRoot_Run the requested command as root (via sudo if requested)_seekConfirmation_Seek user input for yes/no question_setPATH_Add directories to $PATH so script can find executables
csv.bash
Functions to write to a CSV file.
_makeCSV_Creates a new CSV file if one does not already exist_writeCSV_Takes passed arguments and writes them as a comma separated line
dates.bash
Common utilities for working with dates in BASH scripts.
_monthToNumber_Convert a month name to a number_numberToMonth_Convert a month number to its name_parseDate_Takes a string as input and attempts to find a date within it to parse into component parts (day, month, year)_formatDate_Reformats dates into user specified formats
files.bash
Common utilities for working with files.
_listFiles_Find files in a directory. Use either glob or regex._backupFile_Creates a backup of a specified file with .bak extension or optionally to a specified directory._cleanFilename_Cleans a filename of all non-alphanumeric (or user specified) characters and overwrites original_parseFilename_Break a filename into its component parts which and place them into prefixed variables (dir, basename, extension, full path, etc.)_decryptFile_Decrypts a file withopenssl_encryptFile_Encrypts a file withopenssl_ext_Extract the extension from a filename_extract_Extract a compressed file_json2yaml_Convert JSON to YAML uses python_makeSymlink_Creates a symlink and backs up a file which may be overwritten by the new symlink. If the exact same symlink already exists, nothing is done._parseYAML_Convert a YANML file into BASH variables for use in a shell script_readFile_Prints each line of a file_sourceFile_Source a file into a script_uniqueFileName_Ensure a file to be created has a unique filename to avoid overwriting other files_yaml2json_Convert a YAML file to JSON with python
macOS.bash
Functions useful when writing scripts to be run on macOS
_haveScriptableFinder_Determine whether we can script the Finder or not_guiInput_Ask for user input using a Mac dialog box
numbers.bash
Helpers to work with numbers
_fromSeconds_Convert seconds to HH:MM:SS_toSeconds_Converts HH:MM:SS to seconds_countdown_Sleep for a specified amount of time
services.bash
Functions to work with external services
_haveInternet_Tests to see if there is an active Internet connection_httpStatus_Report the HTTP status of a specified URL_pushover_Sends a notification via Pushover (Requires API keys)
testProcessing.bash
Work with strings in your script
_cleanString_Cleans a string of text_stopWords_Removes common stopwords from a string. Requires a sed stopwords file. Customize to your needs._escape_Escapes a string by adding\before special chars_htmlDecode_Decode HTML characters with sed. (Requires sed file)_htmlEncode_Encode HTML characters with sed (Requires sed file)_lower_Convert a string to lowercase_upper_Convert a string to uppercase_ltrim_Removes all leading whitespace (from the left)_regex_Use regex to validate and parse strings_rtrim_Removes all leading whitespace (from the right)_trim_Removes all leading/trailing whitespace_urlEncode_URL encode a string_urlDecode_Decode a URL encoded string
A Note on Code Reuse
I compiled these scripting utilities over many years without having an intention to make them public. As a novice programmer, I have Googled, GitHubbed, and StackExchanged a path to solve my own scripting needs. I often lift a function whole-cloth from a GitHub repo don't keep track of its original location. I have done my best within these files to recreate my footsteps and give credit to the original creators of the code when possible. Unfortunately, I fear that I missed as many as I found. My goal in making this repository public is not to take credit for the code written by others. If you recognize something that I didn't credit, please let me know.
License
MIT