shellcheck improvements

This commit is contained in:
Nathaniel Landau
2021-10-29 15:01:31 -04:00
parent 86300b68c4
commit 1377697ae6
15 changed files with 196 additions and 197 deletions

View File

@@ -436,7 +436,6 @@ _setColors_() {
white=$(tput setaf 231) white=$(tput setaf 231)
blue=$(tput setaf 38) blue=$(tput setaf 38)
yellow=$(tput setaf 11) yellow=$(tput setaf 11)
tan=$(tput setaf 3)
green=$(tput setaf 82) green=$(tput setaf 82)
red=$(tput setaf 1) red=$(tput setaf 1)
purple=$(tput setaf 171) purple=$(tput setaf 171)
@@ -445,7 +444,6 @@ _setColors_() {
white=$(tput setaf 7) white=$(tput setaf 7)
blue=$(tput setaf 38) blue=$(tput setaf 38)
yellow=$(tput setaf 3) yellow=$(tput setaf 3)
tan=$(tput setaf 3)
green=$(tput setaf 2) green=$(tput setaf 2)
red=$(tput setaf 1) red=$(tput setaf 1)
purple=$(tput setaf 13) purple=$(tput setaf 13)
@@ -460,7 +458,6 @@ _setColors_() {
white="\033[0;37m" white="\033[0;37m"
blue="\033[0;34m" blue="\033[0;34m"
yellow="\033[0;33m" yellow="\033[0;33m"
tan="\033[0;33m"
green="\033[1;32m" green="\033[1;32m"
red="\033[0;31m" red="\033[0;31m"
purple="\033[0;35m" purple="\033[0;35m"
@@ -648,7 +645,7 @@ _safeExit_() {
if command rm -rf "${SCRIPT_LOCK}"; then if command rm -rf "${SCRIPT_LOCK}"; then
debug "Removing script lock" debug "Removing script lock"
else else
warning "Script lock could not be removed. Try manually deleting ${tan}'${LOCK_DIR}'" warning "Script lock could not be removed. Try manually deleting ${yellow}'${SCRIPT_LOCK}'"
fi fi
fi fi
@@ -730,6 +727,7 @@ _makeTempDir_() {
debug "\$TMP_DIR=${TMP_DIR}" debug "\$TMP_DIR=${TMP_DIR}"
} }
# shellcheck disable=SC2120
_acquireScriptLock_() { _acquireScriptLock_() {
# DESC: # DESC:
# Acquire script lock to prevent running the same script a second time before the # Acquire script lock to prevent running the same script a second time before the
@@ -746,18 +744,18 @@ _acquireScriptLock_() {
if [[ ${1:-} == 'system' ]]; then if [[ ${1:-} == 'system' ]]; then
_lockDir="${TMPDIR:-/tmp/}$(basename "$0").lock" _lockDir="${TMPDIR:-/tmp/}$(basename "$0").lock"
else else
_lockDir="${TMPDIR:-/tmp/}$(basename "$0").$UID.lock" _lockDir="${TMPDIR:-/tmp/}$(basename "$0").${UID}.lock"
fi fi
if command mkdir "${LOCK_DIR}" 2>/dev/null; then if command mkdir "${_lockDir}" 2>/dev/null; then
readonly SCRIPT_LOCK="${_lockDir}" readonly SCRIPT_LOCK="${_lockDir}"
debug "Acquired script lock: ${yellow}${SCRIPT_LOCK}${purple}" debug "Acquired script lock: ${yellow}${SCRIPT_LOCK}${purple}"
else else
if [ "$(declare -f "_safeExit_")" ]; then if declare -f "_safeExit_" &>/dev/null; then
error "Unable to acquire script lock: ${tan}${LOCK_DIR}${red}" error "Unable to acquire script lock: ${yellow}${_lockDir}${red}"
fatal "If you trust the script isn't running, delete the lock dir" fatal "If you trust the script isn't running, delete the lock dir"
else else
printf "%s\n" "ERROR: Could not acquire script lock. If you trust the script isn't running, delete: ${LOCK_DIR}" printf "%s\n" "ERROR: Could not acquire script lock. If you trust the script isn't running, delete: ${_lockDir}"
exit 1 exit 1
fi fi

View File

@@ -14,6 +14,7 @@ _mainScript_() {
input "This is input text" input "This is input text"
} }
#/_mainsScript_() #/_mainsScript_()
# ################################## Flags and defaults # ################################## Flags and defaults
@@ -52,7 +53,7 @@ _trapCleanup_() {
local _script="${5:-}" local _script="${5:-}"
local _sourced="${6:-}" local _sourced="${6:-}"
if [[ "$(declare -f "fatal")" && "$(declare -f "_printFuncStack_")" ]]; then if declare -f "fatal" &>/dev/null && declare -f "_printFuncStack_" &>/dev/null; then
_funcstack="'$(printf "%s" "${_funcstack}" | sed -E 's/ / < /g')'" _funcstack="'$(printf "%s" "${_funcstack}" | sed -E 's/ / < /g')'"
@@ -65,7 +66,7 @@ _trapCleanup_() {
printf "%s\n" "Fatal error trapped. Exiting..." printf "%s\n" "Fatal error trapped. Exiting..."
fi fi
if [ "$(declare -f "_safeExit_")" ]; then if declare -f _safeExit_ &>/dev/null; then
_safeExit_ 1 _safeExit_ 1
else else
exit 1 exit 1
@@ -87,9 +88,11 @@ _findBaseDir_() {
local _dir local _dir
# Is file sourced? # Is file sourced?
[[ $_ != "$0" ]] \ if [[ ${_} != "${0}" ]]; then
&& _source="${BASH_SOURCE[1]}" \ _source="${BASH_SOURCE[1]}"
|| _source="${BASH_SOURCE[0]}" else
_source="${BASH_SOURCE[0]}"
fi
while [ -h "${_source}" ]; do # Resolve $SOURCE until the file is no longer a symlink while [ -h "${_source}" ]; do # Resolve $SOURCE until the file is no longer a symlink
_dir="$(cd -P "$(dirname "${_source}")" && pwd)" _dir="$(cd -P "$(dirname "${_source}")" && pwd)"
@@ -104,93 +107,92 @@ _sourceUtilities_() {
# Sources utility functions. Absolute paths are required for shellcheck to correctly # Sources utility functions. Absolute paths are required for shellcheck to correctly
# parse the sourced files # parse the sourced files
# ARGS: # ARGS:
# NONE # $1 (Required): Absolute path to the directory containing the utilities
# OUTS: # OUTS:
# 0: Success # 0: Success
# 1: Failure # 1: Failure
# USAGE: # USAGE:
# _sourceUtilities_ # _sourceUtilities_ "$(_findBaseDir_)/../../shell-scripting-templates/utilities"
local _utilsPath local _utilsPath
_utilsPath="$(_findBaseDir_)/../shell-scripting-templates/utilities/" _utilsPath="${1}"
if [ -f "${_utilsPath}/alerts.bash" ]; then if [ -f "${_utilsPath}/alerts.bash" ]; then
source "${_utilsPath}/alerts.bash" source "${_utilsPath}/alerts.bash"
else else
printf "%s\n" "ERROR: alerts.bash not found" printf "%s\n" "ERROR: ${_utilsPath}/alerts.bash not found"
exit 1 exit 1
fi fi
if [ -f "${_utilsPath}/arrays.bash" ]; then if [ -f "${_utilsPath}/arrays.bash" ]; then
source "${_utilsPath}/arrays.bash" source "${_utilsPath}/arrays.bash"
else else
printf "%s\n" "ERROR: arrays.bash not found" printf "%s\n" "ERROR: ${_utilsPath}/arrays.bash not found"
exit 1 exit 1
fi fi
if [ -f "${_utilsPath}/checks.bash" ]; then if [ -f "${_utilsPath}/checks.bash" ]; then
source "${_utilsPath}/checks.bash" source "${_utilsPath}/checks.bash"
else else
printf "%s\n" "ERROR: checks.bash not found" printf "%s\n" "ERROR: ${_utilsPath}/checks.bash not found"
exit 1 exit 1
fi fi
if [ -f "${_utilsPath}/dates.bash" ]; then if [ -f "${_utilsPath}/dates.bash" ]; then
source "${_utilsPath}/dates.bash" source "${_utilsPath}/dates.bash"
else else
printf "%s\n" "ERROR: dates.bash not found" printf "%s\n" "ERROR: ${_utilsPath}/dates.bash not found"
exit 1 exit 1
fi fi
if [ -f "${_utilsPath}/debug.bash" ]; then if [ -f "${_utilsPath}/debug.bash" ]; then
source "${_utilsPath}/debug.bash" source "${_utilsPath}/debug.bash"
else else
printf "%s\n" "ERROR: debug.bash not found" printf "%s\n" "ERROR: ${_utilsPath}/debug.bash not found"
exit 1 exit 1
fi fi
if [ -f "${_utilsPath}/files.bash" ]; then if [ -f "${_utilsPath}/files.bash" ]; then
source "${_utilsPath}/files.bash" source "${_utilsPath}/files.bash"
else else
printf "%s\n" "ERROR: files.bash not found" printf "%s\n" "ERROR: ${_utilsPath}/files.bash not found"
exit 1 exit 1
fi fi
if [ -f "${_utilsPath}/macOS.bash" ]; then if [ -f "${_utilsPath}/macOS.bash" ]; then
source "${_utilsPath}/macOS.bash" source "${_utilsPath}/macOS.bash"
else else
printf "%s\n" "ERROR: macOS.bash not found" printf "%s\n" "ERROR: ${_utilsPath}/macOS.bash not found"
exit 1 exit 1
fi fi
if [ -f "${_utilsPath}/misc.bash" ]; then if [ -f "${_utilsPath}/misc.bash" ]; then
source "${_utilsPath}/misc.bash" source "${_utilsPath}/misc.bash"
else else
printf "%s\n" "ERROR: misc.bash not found" printf "%s\n" "ERROR: ${_utilsPath}/misc.bash not found"
exit 1 exit 1
fi fi
if [ -f "${_utilsPath}/services.bash" ]; then if [ -f "${_utilsPath}/services.bash" ]; then
source "${_utilsPath}/services.bash" source "${_utilsPath}/services.bash"
else else
printf "%s\n" "ERROR: services.bash not found" printf "%s\n" "ERROR: ${_utilsPath}/services.bash not found"
exit 1 exit 1
fi fi
if [ -f "${_utilsPath}/strings.bash" ]; then if [ -f "${_utilsPath}/strings.bash" ]; then
source "${_utilsPath}/strings.bash" source "${_utilsPath}/strings.bash"
else else
printf "%s\n" "ERROR: strings.bash not found" printf "%s\n" "ERROR: ${_utilsPath}/strings.bash not found"
exit 1 exit 1
fi fi
if [ -f "${_utilsPath}/template_utils.bash" ]; then if [ -f "${_utilsPath}/template_utils.bash" ]; then
source "${_utilsPath}/template_utils.bash" source "${_utilsPath}/template_utils.bash"
else else
printf "%s\n" "ERROR: template_utils.bash not found" printf "%s\n" "ERROR: ${_utilsPath}/template_utils.bash not found"
exit 1 exit 1
fi fi
} }
_parseOptions_() { _parseOptions_() {
@@ -219,7 +221,7 @@ _parseOptions_() {
_options+=("-${_c}") # Add current char to options _options+=("-${_c}") # Add current char to options
# If option takes a required argument, and it's not the last char make # If option takes a required argument, and it's not the last char make
# the rest of the string its argument # the rest of the string its argument
if [[ ${_optstring} == *"${_c}:"* && ${1:i+1} ]]; then if [[ ${_optstring} == *"${_c}:"* && -n ${1:i+1} ]]; then
_options+=("${1:i+1}") _options+=("${1:i+1}")
break break
fi fi
@@ -265,10 +267,10 @@ _parseOptions_() {
break break
;; ;;
*) *)
if [ "$(declare -f "_safeExit_")" ]; then if declare -f _safeExit_ &>/dev/null; then
fatal "invalid option: $1" fatal "invalid option: $1"
else else
printf "%s\n" "Invalid option: $1" printf "%s\n" "ERROR: Invalid option: $1"
exit 1 exit 1
fi fi
;; ;;
@@ -337,7 +339,7 @@ IFS=$' \n\t'
# set -o xtrace # set -o xtrace
# Source utility functions # Source utility functions
_sourceUtilities_ _sourceUtilities_ "$(_findBaseDir_)/../shell-scripting-templates/utilities"
# Initialize color constants # Initialize color constants
_setColors_ _setColors_

View File

@@ -52,7 +52,6 @@ _setColors_() {
white=$(tput setaf 231) white=$(tput setaf 231)
blue=$(tput setaf 38) blue=$(tput setaf 38)
yellow=$(tput setaf 11) yellow=$(tput setaf 11)
tan=$(tput setaf 3)
green=$(tput setaf 82) green=$(tput setaf 82)
red=$(tput setaf 1) red=$(tput setaf 1)
purple=$(tput setaf 171) purple=$(tput setaf 171)
@@ -61,7 +60,6 @@ _setColors_() {
white=$(tput setaf 7) white=$(tput setaf 7)
blue=$(tput setaf 38) blue=$(tput setaf 38)
yellow=$(tput setaf 3) yellow=$(tput setaf 3)
tan=$(tput setaf 3)
green=$(tput setaf 2) green=$(tput setaf 2)
red=$(tput setaf 1) red=$(tput setaf 1)
purple=$(tput setaf 13) purple=$(tput setaf 13)
@@ -76,7 +74,6 @@ _setColors_() {
white="\033[0;37m" white="\033[0;37m"
blue="\033[0;34m" blue="\033[0;34m"
yellow="\033[0;33m" yellow="\033[0;33m"
tan="\033[0;33m"
green="\033[1;32m" green="\033[1;32m"
red="\033[0;31m" red="\033[0;31m"
purple="\033[0;35m" purple="\033[0;35m"
@@ -241,10 +238,17 @@ _printFuncStack_() {
# NOTE: # NOTE:
# Does not print functions from the alert class # Does not print functions from the alert class
local _i local _i
_funcStackResponse=() declare -a _funcStackResponse=()
for ((_i = 1; _i < ${#BASH_SOURCE[@]}; _i++)); do for ((_i = 1; _i < ${#BASH_SOURCE[@]}; _i++)); do
case "${FUNCNAME[$_i]}" in "_alert_" | "_trapCleanup_" | fatal | error | warning | notice | info | debug | dryrun | header | success) continue ;; esac case "${FUNCNAME[${_i}]}" in
_funcStackResponse+=("${FUNCNAME[$_i]}:$(basename "${BASH_SOURCE[$_i]}"):${BASH_LINENO[_i - 1]}") _alert_ | _trapCleanup_ | fatal | error | warning | notice | info | debug | dryrun | header | success)
continue
;;
*)
_funcStackResponse+=("${FUNCNAME[${_i}]}:$(basename "${BASH_SOURCE[${_i}]}"):${BASH_LINENO[_i - 1]}")
;;
esac
done done
printf "( " printf "( "
printf %s "${_funcStackResponse[0]}" printf %s "${_funcStackResponse[0]}"
@@ -264,7 +268,7 @@ _safeExit_() {
if command rm -rf "${SCRIPT_LOCK}"; then if command rm -rf "${SCRIPT_LOCK}"; then
debug "Removing script lock" debug "Removing script lock"
else else
warning "Script lock could not be removed. Try manually deleting ${tan}'${LOCK_DIR}'" warning "Script lock could not be removed. Try manually deleting ${yellow}'${SCRIPT_LOCK}'"
fi fi
fi fi
@@ -303,7 +307,7 @@ _trapCleanup_() {
local _script="${5:-}" local _script="${5:-}"
local _sourced="${6:-}" local _sourced="${6:-}"
if [[ "$(declare -f "fatal")" && "$(declare -f "_printFuncStack_")" ]]; then if declare -f "fatal" &>/dev/null && declare -f "_printFuncStack_" &>/dev/null; then
_funcstack="'$(printf "%s" "${_funcstack}" | sed -E 's/ / < /g')'" _funcstack="'$(printf "%s" "${_funcstack}" | sed -E 's/ / < /g')'"
@@ -316,7 +320,7 @@ _trapCleanup_() {
printf "%s\n" "Fatal error trapped. Exiting..." printf "%s\n" "Fatal error trapped. Exiting..."
fi fi
if [ "$(declare -f "_safeExit_")" ]; then if declare -f _safeExit_ &>/dev/null; then
_safeExit_ 1 _safeExit_ 1
else else
exit 1 exit 1
@@ -346,6 +350,7 @@ _makeTempDir_() {
debug "\$TMP_DIR=${TMP_DIR}" debug "\$TMP_DIR=${TMP_DIR}"
} }
# shellcheck disable=SC2120
_acquireScriptLock_() { _acquireScriptLock_() {
# DESC: # DESC:
# Acquire script lock to prevent running the same script a second time before the # Acquire script lock to prevent running the same script a second time before the
@@ -362,18 +367,18 @@ _acquireScriptLock_() {
if [[ ${1:-} == 'system' ]]; then if [[ ${1:-} == 'system' ]]; then
_lockDir="${TMPDIR:-/tmp/}$(basename "$0").lock" _lockDir="${TMPDIR:-/tmp/}$(basename "$0").lock"
else else
_lockDir="${TMPDIR:-/tmp/}$(basename "$0").$UID.lock" _lockDir="${TMPDIR:-/tmp/}$(basename "$0").${UID}.lock"
fi fi
if command mkdir "${LOCK_DIR}" 2>/dev/null; then if command mkdir "${_lockDir}" 2>/dev/null; then
readonly SCRIPT_LOCK="${_lockDir}" readonly SCRIPT_LOCK="${_lockDir}"
debug "Acquired script lock: ${yellow}${SCRIPT_LOCK}${purple}" debug "Acquired script lock: ${yellow}${SCRIPT_LOCK}${purple}"
else else
if [ "$(declare -f "_safeExit_")" ]; then if declare -f "_safeExit_" &>/dev/null; then
error "Unable to acquire script lock: ${tan}${LOCK_DIR}${red}" error "Unable to acquire script lock: ${yellow}${_lockDir}${red}"
fatal "If you trust the script isn't running, delete the lock dir" fatal "If you trust the script isn't running, delete the lock dir"
else else
printf "%s\n" "ERROR: Could not acquire script lock. If you trust the script isn't running, delete: ${LOCK_DIR}" printf "%s\n" "ERROR: Could not acquire script lock. If you trust the script isn't running, delete: ${_lockDir}"
exit 1 exit 1
fi fi
@@ -426,7 +431,7 @@ _useGNUutils_() {
# NOTES: # NOTES:
# GNU utilities can be added to MacOS using Homebrew # GNU utilities can be added to MacOS using Homebrew
[ ! "$(declare -f "_setPATH_")" ] && fatal "${FUNCNAME[0]} needs function _setPATH_" ! declare -f "_setPATH_" &>/dev/null && fatal "${FUNCNAME[0]} needs function _setPATH_"
if _setPATH_ \ if _setPATH_ \
"/usr/local/opt/gnu-tar/libexec/gnubin" \ "/usr/local/opt/gnu-tar/libexec/gnubin" \
@@ -466,7 +471,7 @@ _parseOptions_() {
_options+=("-${_c}") # Add current char to options _options+=("-${_c}") # Add current char to options
# If option takes a required argument, and it's not the last char make # If option takes a required argument, and it's not the last char make
# the rest of the string its argument # the rest of the string its argument
if [[ ${_optstring} == *"${_c}:"* && ${1:i+1} ]]; then if [[ ${_optstring} == *"${_c}:"* && -n ${1:i+1} ]]; then
_options+=("${1:i+1}") _options+=("${1:i+1}")
break break
fi fi
@@ -512,10 +517,10 @@ _parseOptions_() {
break break
;; ;;
*) *)
if [ "$(declare -f "_safeExit_")" ]; then if declare -f _safeExit_ &>/dev/null; then
fatal "invalid option: $1" fatal "invalid option: $1"
else else
printf "%s\n" "Invalid option: $1" printf "%s\n" "ERROR: Invalid option: $1"
exit 1 exit 1
fi fi
;; ;;

52
test/fixtures/test.md vendored
View File

@@ -1,20 +1,22 @@
# About # About
This repository contains everything needed to bootstrap and configure new Mac computer. Included here are: This repository contains everything needed to bootstrap and configure new Mac computer. Included here are:
* dotfiles - dotfiles
* ~/bin/ scripts - ~/bin/ scripts
* Configuration files - Configuration files
* Scripting templates and utilities - Scripting templates and utilities
* `install.sh`, a script to put everything where it needs to go - `install.sh`, a script to put everything where it needs to go
**Disclaimer:** *I am not a professional programmer and I bear no responsibility whatsoever if any of these scripts wipes your computer, destroys your data, crashes your car, or otherwise causes mayhem and destruction. USE AT YOUR OWN RISK.* **Disclaimer:** _I am not a professional programmer and I bear no responsibility whatsoever if any of these scripts wipes your computer, destroys your data, crashes your car, or otherwise causes mayhem and destruction. USE AT YOUR OWN RISK._
## install.sh ## install.sh
This script runs through a series of tasks to configure a new computer. There are three distinct areas of `install.sh` which are executed in order. These are: This script runs through a series of tasks to configure a new computer. There are three distinct areas of `install.sh` which are executed in order. These are:
1. **Bootstrapping** - Installing base components such as Command Line Tools, Homebrew, Node, RVM, etc. 1. **Bootstrapping** - Installing base components such as Command Line Tools, Homebrew, Node, RVM, etc.
2. **Installation** - Symlinking dotfiles and installing executables such as NPM Packages, Homebrew Casks, etc. 2. **Installation** - Symlinking dotfiles and installing executables such as NPM Packages, Homebrew Casks, etc.
3. **Configuration** - Configures installed packages and apps. 3. **Configuration** - Configures installed packages and apps.
The files are organized into three subdirectories. The files are organized into three subdirectories.
@@ -32,20 +34,20 @@ dotfiles
└── scripting/ └── scripting/
``` ```
* **bin** - Symlinked to `~/bin` and is added to your `$PATH`. - **bin** - Symlinked to `~/bin` and is added to your `$PATH`.
* **config** - Contains the elements needed to configure your environment and specific apps. - **config** - Contains the elements needed to configure your environment and specific apps.
* config/**bash** - Files in this directory are *sourced* by `.bash_profile`. - config/**bash** - Files in this directory are _sourced_ by `.bash_profile`.
* config/**shell** - Files here are symlinked to your local environment. Ahem, dotfiles. - config/**shell** - Files here are symlinked to your local environment. Ahem, dotfiles.
* **lib** - Contains the scripts and configuration for `install.sh` - **lib** - Contains the scripts and configuration for `install.sh`
* lib/**bootstrap** - Scripts here are executed by `install.sh` first. - lib/**bootstrap** - Scripts here are executed by `install.sh` first.
* lib/**configure** - Scripts here are exectuted by `install.sh` after packages have been installed - lib/**configure** - Scripts here are executed by `install.sh` after packages have been installed
* **config-install.yaml** - This YAML file contains the list of symlinks to be created, as well as the packages to be installed. - **config-install.yaml** - This YAML file contains the list of symlinks to be created, as well as the packages to be installed.
* **scripting** - This directory contains bash scripting utilities and templates which I re-use often. - **scripting** - This directory contains bash scripting utilities and templates which I re-use often.
**IMPORTANT:** Unless you want to use my defaults, make sure you do the following: **IMPORTANT:** Unless you want to use my defaults, make sure you do the following:
* Edit `config-install.yaml` to reflect your preferred packages - Edit `config-install.yaml` to reflect your preferred packages
* Review the files in `config/` to configure your own aliases, preferences, etc. - Review the files in `config/` to configure your own aliases, preferences, etc.
#### Private Files #### Private Files
@@ -60,6 +62,7 @@ Within the private directory you can write your own install script to configure
If `private/privateInstall.sh` exists, `install.sh` will invoke it. If `private/privateInstall.sh` exists, `install.sh` will invoke it.
## Cloning this repo to a new computer ## Cloning this repo to a new computer
The first step needed to use these dotfiles is to clone this repo into the $HOME directory. To make this easy, I created [a gist](https://gist.github.com/natelandau/b6ec165862277f3a7a4beff76da53a9c) which can easily be run with the following command: The first step needed to use these dotfiles is to clone this repo into the $HOME directory. To make this easy, I created [a gist](https://gist.github.com/natelandau/b6ec165862277f3a7a4beff76da53a9c) which can easily be run with the following command:
``` ```
@@ -68,12 +71,13 @@ curl -SL https://gist.githubusercontent.com/natelandau/b3e1dfba7491137f0a0f5e257
This gist creates a script `~/bootstrap.sh` in your home directory which completes the following tasks This gist creates a script `~/bootstrap.sh` in your home directory which completes the following tasks
1. Creates a new public SSH key if needed 1. Creates a new public SSH key if needed
2. Copies your public key to your clipboard 2. Copies your public key to your clipboard
3. Opens Github to allow you to add this public key to your 'known keys' 3. Opens Github to allow you to add this public key to your 'known keys'
4. Clones this dotfiles repo to your home directory 4. Clones this dotfiles repo to your home directory
See. Easy. Now you're ready to run `~/dotfiles/install.sh` and get your new computer working. See. Easy. Now you're ready to run `~/dotfiles/install.sh` and get your new computer working.
### A Note on Code Reuse ### A Note on Code Reuse
Many of the scripts, configuration files, and other information herein were created by me over many years without ever having the intention to make them public. As a novice programmer, I have Googled, GitHubbed, and StackExchanged a path to solve my own scripting needs. Quite often I would lift a function whole-cloth from a GitHub repo and not keep track of it's 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 of making this repository public is not to take credit for the wonderful code written by others. If you recognize or wrote something here that I didn't credit, please let me know. Many of the scripts, configuration files, and other information herein were created by me over many years without ever having the intention to make them public. As a novice programmer, I have Googled, GitHubbed, and StackExchanged a path to solve my own scripting needs. Quite often I would lift a function whole-cloth from a GitHub repo and not keep track of it's 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 of making this repository public is not to take credit for the wonderful code written by others. If you recognize or wrote something here that I didn't credit, please let me know.

View File

@@ -21,7 +21,6 @@ _setColors_() {
white=$(tput setaf 231) white=$(tput setaf 231)
blue=$(tput setaf 38) blue=$(tput setaf 38)
yellow=$(tput setaf 11) yellow=$(tput setaf 11)
tan=$(tput setaf 3)
green=$(tput setaf 82) green=$(tput setaf 82)
red=$(tput setaf 1) red=$(tput setaf 1)
purple=$(tput setaf 171) purple=$(tput setaf 171)
@@ -30,7 +29,6 @@ _setColors_() {
white=$(tput setaf 7) white=$(tput setaf 7)
blue=$(tput setaf 38) blue=$(tput setaf 38)
yellow=$(tput setaf 3) yellow=$(tput setaf 3)
tan=$(tput setaf 3)
green=$(tput setaf 2) green=$(tput setaf 2)
red=$(tput setaf 1) red=$(tput setaf 1)
purple=$(tput setaf 13) purple=$(tput setaf 13)
@@ -45,7 +43,6 @@ _setColors_() {
white="\033[0;37m" white="\033[0;37m"
blue="\033[0;34m" blue="\033[0;34m"
yellow="\033[0;33m" yellow="\033[0;33m"
tan="\033[0;33m"
green="\033[1;32m" green="\033[1;32m"
red="\033[0;31m" red="\033[0;31m"
purple="\033[0;35m" purple="\033[0;35m"
@@ -210,10 +207,17 @@ _printFuncStack_() {
# NOTE: # NOTE:
# Does not print functions from the alert class # Does not print functions from the alert class
local _i local _i
_funcStackResponse=() declare -a _funcStackResponse=()
for ((_i = 1; _i < ${#BASH_SOURCE[@]}; _i++)); do for ((_i = 1; _i < ${#BASH_SOURCE[@]}; _i++)); do
case "${FUNCNAME[$_i]}" in "_alert_" | "_trapCleanup_" | fatal | error | warning | notice | info | debug | dryrun | header | success) continue ;; esac case "${FUNCNAME[${_i}]}" in
_funcStackResponse+=("${FUNCNAME[$_i]}:$(basename "${BASH_SOURCE[$_i]}"):${BASH_LINENO[_i - 1]}") _alert_ | _trapCleanup_ | fatal | error | warning | notice | info | debug | dryrun | header | success)
continue
;;
*)
_funcStackResponse+=("${FUNCNAME[${_i}]}:$(basename "${BASH_SOURCE[${_i}]}"):${BASH_LINENO[_i - 1]}")
;;
esac
done done
printf "( " printf "( "
printf %s "${_funcStackResponse[0]}" printf %s "${_funcStackResponse[0]}"
@@ -319,7 +323,7 @@ _clearLine_() {
# USAGE: # USAGE:
# _clearLine_ "2" # _clearLine_ "2"
[ ! "$(declare -f "_isTerminal_")" ] && fatal "${FUNCNAME[0]} needs function _isTerminal_" ! declare -f _isTerminal_ &>/dev/null && fatal "${FUNCNAME[0]} needs function _isTerminal_"
local i local i
if _isTerminal_; then if _isTerminal_; then

View File

@@ -19,7 +19,7 @@ _dedupeArray_() {
declare -a _uniqueArray declare -a _uniqueArray
local _i local _i
for _i in "$@"; do for _i in "$@"; do
{ [[ -z ${_i} || ${_tmpArray[${_i}]:-} ]]; } && continue { [[ -z ${_i} || -n ${_tmpArray[${_i}]:-} ]]; } && continue
_uniqueArray+=("${_i}") && _tmpArray[${_i}]=x _uniqueArray+=("${_i}") && _tmpArray[${_i}]=x
done done
printf '%s\n' "${_uniqueArray[@]}" printf '%s\n' "${_uniqueArray[@]}"
@@ -50,13 +50,16 @@ _forEachDo_() {
if [[ ${_func} == *"$"* ]]; then if [[ ${_func} == *"$"* ]]; then
eval "${_func}" eval "${_func}"
else else
[ ! "$(declare -f "${_func}")" ] && fatal "${FUNCNAME[0]} could not find function ${_func}" if declare -f "${_func}" &>/dev/null; then
eval "${_func}" "'${_it}'" eval "${_func}" "'${_it}'"
else
fatal "${FUNCNAME[0]} could not find function ${_func}"
fi
fi fi
declare -i _ret="$?" declare -i _ret="$?"
if [[ ${_ret} -ne 0 ]]; then if [[ ${_ret} -ne 0 ]]; then
return ${_ret} return "${_ret}"
fi fi
done done
} }
@@ -85,9 +88,12 @@ _forEachValidate_() {
if [[ ${_func} == *"$"* ]]; then if [[ ${_func} == *"$"* ]]; then
eval "${_func}" eval "${_func}"
else else
[ ! "$(declare -f "${_func}")" ] && fatal "${FUNCNAME[0]} could not find function ${_func}" if ! declare -f "${_func}"; then
fatal "${FUNCNAME[0]} could not find function ${_func}"
else
eval "${_func}" "'${_it}'" eval "${_func}" "'${_it}'"
fi fi
fi
declare -i _ret="$?" declare -i _ret="$?"
if [[ ${_ret} -ne 0 ]]; then if [[ ${_ret} -ne 0 ]]; then
@@ -255,7 +261,7 @@ _inArray_() {
case ${opt} in case ${opt} in
i | I) i | I)
#shellcheck disable=SC2064 #shellcheck disable=SC2064
trap "$(shopt -p nocasematch)" RETURN # reset nocasematch when function exits trap '$(shopt -p nocasematch)' RETURN # reset nocasematch when function exits
shopt -s nocasematch # Use case-insensitive regex shopt -s nocasematch # Use case-insensitive regex
;; ;;
*) fatal "Unrecognized option '${1}' passed to ${FUNCNAME[0]}. Exiting." ;; *) fatal "Unrecognized option '${1}' passed to ${FUNCNAME[0]}. Exiting." ;;
@@ -410,14 +416,14 @@ _setDiff_() {
declare -a _setdiffC=() declare -a _setdiffC=()
for _a in "${_setdiffA[@]}"; do for _a in "${_setdiffA[@]}"; do
_skip= _skip=0
for _b in "${_setdiffB[@]}"; do for _b in "${_setdiffB[@]}"; do
if [[ ${_a} == "${_b}" ]]; then if [[ ${_a} == "${_b}" ]]; then
_skip=1 _skip=1
break break
fi fi
done done
[[ "${_skip}" ]] || _setdiffC=("${_setdiffC[@]}" "${_a}") [[ ${_skip} -eq 1 ]] || _setdiffC=("${_setdiffC[@]}" "${_a}")
done done
if [[ ${#_setdiffC[@]} == 0 ]]; then if [[ ${#_setdiffC[@]} == 0 ]]; then

View File

@@ -112,7 +112,7 @@ _isEmail_() {
[[ $# == 0 ]] && fatal "Missing required argument to ${FUNCNAME[0]}" [[ $# == 0 ]] && fatal "Missing required argument to ${FUNCNAME[0]}"
#shellcheck disable=SC2064 #shellcheck disable=SC2064
trap "$(shopt -p nocasematch)" RETURN # reset nocasematch when function exits trap '$(shopt -p nocasematch)' RETURN # reset nocasematch when function exits
shopt -s nocasematch # Use case-insensitive regex shopt -s nocasematch # Use case-insensitive regex
local _emailRegex local _emailRegex
@@ -280,7 +280,7 @@ _rootAvailable_() {
elif [[ -z ${1:-} ]]; then elif [[ -z ${1:-} ]]; then
debug 'Sudo: Updating cached credentials ...' debug 'Sudo: Updating cached credentials ...'
if sudo -v; then if sudo -v; then
if [[ $(sudo -H -- "$BASH" -c 'printf "%s" "$EUID"') -eq 0 ]]; then if [[ $(sudo -H -- "${BASH}" -c 'printf "%s" "$EUID"') -eq 0 ]]; then
_superuser=true _superuser=true
else else
_superuser=false _superuser=false

View File

@@ -231,7 +231,7 @@ _parseDate_() {
PARSE_DATE_DAY="" PARSE_DATE_HOUR="" PARSE_DATE_MINUTE="" PARSE_DATE_DAY="" PARSE_DATE_HOUR="" PARSE_DATE_MINUTE=""
#shellcheck disable=SC2064 #shellcheck disable=SC2064
trap "$(shopt -p nocasematch)" RETURN # reset nocasematch when function exits trap '$(shopt -p nocasematch)' RETURN # reset nocasematch when function exits
shopt -s nocasematch # Use case-insensitive regex shopt -s nocasematch # Use case-insensitive regex
debug "_parseDate_() input: ${_stringToTest}" debug "_parseDate_() input: ${_stringToTest}"
@@ -446,7 +446,7 @@ _parseDate_() {
# # MMDD or DDYY # # MMDD or DDYY
# elif [[ "${_stringToTest}" =~ .*(([0-9]{2})([0-9]{2})).* ]]; then # elif [[ "${_stringToTest}" =~ .*(([0-9]{2})([0-9]{2})).* ]]; then
# debug "regex match: ${tan}MMDD or DDMM${purple}" # debug "regex match: MMDD or DDMM"
# PARSE_DATE_FOUND="${BASH_REMATCH[1]}" # PARSE_DATE_FOUND="${BASH_REMATCH[1]}"
# # Figure out if days are months or vice versa # # Figure out if days are months or vice versa
@@ -496,17 +496,6 @@ _parseDate_() {
[[ -z ${PARSE_DATE_MINUTE:-} ]] || debug "\$PARSE_DATE_MINUTE: ${PARSE_DATE_MINUTE}" [[ -z ${PARSE_DATE_MINUTE:-} ]] || debug "\$PARSE_DATE_MINUTE: ${PARSE_DATE_MINUTE}"
shopt -u nocasematch shopt -u nocasematch
# Output results for BATS tests
if [ "${automated_test_in_progress:-}" ]; then
echo "PARSE_DATE_FOUND: ${PARSE_DATE_FOUND}"
echo "PARSE_DATE_YEAR: ${PARSE_DATE_YEAR}"
echo "PARSE_DATE_MONTH: ${PARSE_DATE_MONTH}"
echo "PARSE_DATE_MONTH_NAME: ${PARSE_DATE_MONTH_NAME}"
echo "PARSE_DATE_DAY: ${PARSE_DATE_DAY}"
echo "PARSE_DATE_HOUR: ${PARSE_DATE_HOUR}"
echo "PARSE_DATE_MINUTE: ${PARSE_DATE_MINUTE}"
fi
} }
_readableUnixTimestamp_() { _readableUnixTimestamp_() {
@@ -570,5 +559,5 @@ _toSeconds_() {
_s="$3" _s="$3"
fi fi
printf "%s\n" "$((10#$_h * 3600 + 10#$_m * 60 + 10#$_s))" printf "%s\n" "$((10#${_h} * 3600 + 10#${_m} * 60 + 10#${_s}))"
} }

View File

@@ -56,11 +56,11 @@ _printArray_() {
local _lineNumber="${2:-}" local _lineNumber="${2:-}"
declare -n _arr="${1}" declare -n _arr="${1}"
[[ ${VERBOSE} != true ]] && return 0 [[ ${VERBOSE:-} != true ]] && return 0
debug "Printing contents of \${${_arrayName}[@]}" "${_lineNumber}" debug "Printing contents of \${${_arrayName}[@]}" "${_lineNumber}"
for _k in "${!_arr[@]}"; do for _k in "${!_arr[@]}"; do
debug "${_k} = ${_arr[$_k]}" debug "${_k} = ${_arr[${_k}]}"
done done
} }

View File

@@ -48,34 +48,29 @@ _backupFile_() {
local _newFilename local _newFilename
# Error handling # Error handling
[ ! "$(declare -f "_execute_")" ] \ declare -f _execute_ &>/dev/null || fatal "_backupFile_ needs function _execute_"
&& { declare -f _createUniqueFilename_ &>/dev/null || fatal "_backupFile_ needs function _createUniqueFilename_"
fatal "_backupFile_ needs function _execute_"
}
[ ! "$(declare -f "_createUniqueFilename_")" ] \
&& {
fatal "_backupFile_ needs function _createUniqueFilename_"
}
[ ! -e "${_fileToBackup}" ] \ [ ! -e "${_fileToBackup}" ] \
&& { && {
debug "Source '${_fileToBackup}' not found" debug "Source '${_fileToBackup}' not found"
return 1 return 1
} }
if [ ${_useDirectory} == true ]; then if [[ ${_useDirectory} == true ]]; then
[ ! -d "${_backupDir}" ] \ [ ! -d "${_backupDir}" ] \
&& _execute_ "mkdir -p \"${_backupDir}\"" "Creating backup directory" && _execute_ "mkdir -p \"${_backupDir}\"" "Creating backup directory"
_newFilename="$(_createUniqueFilename_ "${_backupDir}/${_fileToBackup#.}")" _newFilename="$(_createUniqueFilename_ "${_backupDir}/${_fileToBackup#.}")"
if [ ${_moveFile} == true ]; then if [[ ${_moveFile} == true ]]; then
_execute_ "mv \"${_fileToBackup}\" \"${_backupDir}/${_newFilename##*/}\"" "Moving: '${_fileToBackup}' to '${_backupDir}/${_newFilename##*/}'" _execute_ "mv \"${_fileToBackup}\" \"${_backupDir}/${_newFilename##*/}\"" "Moving: '${_fileToBackup}' to '${_backupDir}/${_newFilename##*/}'"
else else
_execute_ "cp -R \"${_fileToBackup}\" \"${_backupDir}/${_newFilename##*/}\"" "Backing up: '${_fileToBackup}' to '${_backupDir}/${_newFilename##*/}'" _execute_ "cp -R \"${_fileToBackup}\" \"${_backupDir}/${_newFilename##*/}\"" "Backing up: '${_fileToBackup}' to '${_backupDir}/${_newFilename##*/}'"
fi fi
else else
_newFilename="$(_createUniqueFilename_ "${_fileToBackup}.bak")" _newFilename="$(_createUniqueFilename_ "${_fileToBackup}.bak")"
if [ ${_moveFile} == true ]; then if [[ ${_moveFile} == true ]]; then
_execute_ "mv \"${_fileToBackup}\" \"${_newFilename}\"" "Moving '${_fileToBackup}' to '${_newFilename}'" _execute_ "mv \"${_fileToBackup}\" \"${_newFilename}\"" "Moving '${_fileToBackup}' to '${_newFilename}'"
else else
_execute_ "cp -R \"${_fileToBackup}\" \"${_newFilename}\"" "Backing up '${_fileToBackup}' to '${_newFilename}'" _execute_ "cp -R \"${_fileToBackup}\" \"${_newFilename}\"" "Backing up '${_fileToBackup}' to '${_newFilename}'"
@@ -110,10 +105,8 @@ _createUniqueFilename_() {
case ${opt} in case ${opt} in
i | I) _internalInteger=true ;; i | I) _internalInteger=true ;;
*) *)
{ error "Unrecognized option '${1}' passed to ${FUNCNAME[0]}" "${LINENO}"
error "Unrecognized option '${1}' passed to _createUniqueFilename_" "${LINENO}"
return 1 return 1
}
;; ;;
esac esac
done done
@@ -142,7 +135,7 @@ _createUniqueFilename_() {
_originalFile="$(basename "${_fullFile}")" _originalFile="$(basename "${_fullFile}")"
#shellcheck disable=SC2064 #shellcheck disable=SC2064
trap "$(shopt -p nocasematch)" RETURN # reset nocasematch when function exits trap '$(shopt -p nocasematch)' RETURN # reset nocasematch when function exits
shopt -s nocasematch # Use case-insensitive regex shopt -s nocasematch # Use case-insensitive regex
# Detect some common multi-extensions # Detect some common multi-extensions
@@ -155,18 +148,18 @@ _createUniqueFilename_() {
_fn="${_originalFile}" _fn="${_originalFile}"
for ((i = 0; i < _levels; i++)); do for ((i = 0; i < _levels; i++)); do
_ext=${_fn##*.} _ext=${_fn##*.}
if [[ $i == 0 ]]; then if [[ ${i} == 0 ]]; then
_extension=${_ext}${_extension:-} _extension=${_ext}${_extension:-}
else else
_extension=${_ext}.${_extension:-} _extension=${_ext}.${_extension:-}
fi fi
_fn=${_fn%.$_ext} _fn=${_fn%.${_ext}}
done done
if [[ ${_extension} == "${_originalFile}" ]]; then if [[ ${_extension} == "${_originalFile}" ]]; then
_extension="" _extension=""
else else
_originalFile="${_originalFile%.$_extension}" _originalFile="${_originalFile%.${_extension}}"
_extension=".${_extension}" _extension=".${_extension}"
fi fi
@@ -212,9 +205,9 @@ _decryptFile_() {
local _fileToDecrypt="${1:?_decryptFile_ needs a file}" local _fileToDecrypt="${1:?_decryptFile_ needs a file}"
local _defaultName="${_fileToDecrypt%.enc}" local _defaultName="${_fileToDecrypt%.enc}"
local _decryptedFile="${2:-$_defaultName.decrypt}" local _decryptedFile="${2:-${_defaultName}.decrypt}"
[ ! "$(declare -f "_execute_")" ] && fatal "need function _execute_" declare -f _execute_ &>/dev/null || fatal "${FUNCNAME[0]} needs function _execute_"
if ! command -v openssl &>/dev/null; then if ! command -v openssl &>/dev/null; then
fatal "openssl not found" fatal "openssl not found"
@@ -247,13 +240,13 @@ _encryptFile_() {
local _fileToEncrypt="${1:?_encodeFile_ needs a file}" local _fileToEncrypt="${1:?_encodeFile_ needs a file}"
local _defaultName="${_fileToEncrypt%.decrypt}" local _defaultName="${_fileToEncrypt%.decrypt}"
local _encryptedFile="${2:-$_defaultName.enc}" local _encryptedFile="${2:-${_defaultName}.enc}"
[[ $# == 0 ]] && fatal "Missing required argument to ${FUNCNAME[0]}" [[ $# == 0 ]] && fatal "Missing required argument to ${FUNCNAME[0]}"
[ ! -f "${_fileToEncrypt}" ] && return 1 [ ! -f "${_fileToEncrypt}" ] && return 1
[ ! "$(declare -f "_execute_")" ] && fatal "need function _execute_" declare -f _execute_ &>/dev/null || fatal "${FUNCNAME[0]} needs function _execute_"
if ! command -v openssl &>/dev/null; then if ! command -v openssl &>/dev/null; then
fatal "openssl not found" fatal "openssl not found"
@@ -295,7 +288,7 @@ _extractArchive_() {
set -- "$@" "${1:0:-2}" set -- "$@" "${1:0:-2}"
;; ;;
*.bz2) bunzip2 "$1" ;; *.bz2) bunzip2 "$1" ;;
*.deb) dpkg-deb -x${_vv} "$1" "${1:0:-4}" ;; *.deb) dpkg-deb -x"${_vv}" "$1" "${1:0:-4}" ;;
*.pax.gz) *.pax.gz)
gunzip "$1" gunzip "$1"
set -- "$@" "${1:0:-3}" set -- "$@" "${1:0:-3}"
@@ -304,7 +297,7 @@ _extractArchive_() {
*.pax) pax -r -f "$1" ;; *.pax) pax -r -f "$1" ;;
*.pkg) pkgutil --expand "$1" "${1:0:-4}" ;; *.pkg) pkgutil --expand "$1" "${1:0:-4}" ;;
*.rar) unrar x "$1" ;; *.rar) unrar x "$1" ;;
*.rpm) rpm2cpio "$1" | cpio -idm${_vv} ;; *.rpm) rpm2cpio "$1" | cpio -idm"${_vv}" ;;
*.tar) tar "x${_vv}f" "$1" ;; *.tar) tar "x${_vv}f" "$1" ;;
*.txz) *.txz)
mv "$1" "${1:0:-4}.tar.xz" mv "$1" "${1:0:-4}.tar.xz"
@@ -388,15 +381,15 @@ _fileExtension_() {
esac esac
fi fi
_fn="$_file" _fn="${_file}"
for ((i = 0; i < _levels; i++)); do for ((i = 0; i < _levels; i++)); do
_ext=${_fn##*.} _ext=${_fn##*.}
if [[ $i == 0 ]]; then if [[ ${i} == 0 ]]; then
_exts=${_ext}${_exts:-} _exts=${_ext}${_exts:-}
else else
_exts=${_ext}.${_exts:-} _exts=${_ext}.${_exts:-}
fi fi
_fn=${_fn%.$_ext} _fn=${_fn%.${_ext}}
done done
[[ ${_file} == "${_exts}" ]] && return 1 [[ ${_file} == "${_exts}" ]] && return 1
@@ -543,7 +536,7 @@ _makeSymlink_() {
local _onlyShowChanged=false local _onlyShowChanged=false
while getopts ":cCnNsS" opt; do while getopts ":cCnNsS" opt; do
case $opt in case ${opt} in
n | N) _backupOriginal=false ;; n | N) _backupOriginal=false ;;
s | S) _useSudo=true ;; s | S) _useSudo=true ;;
c | C) _onlyShowChanged=true ;; c | C) _onlyShowChanged=true ;;
@@ -552,12 +545,12 @@ _makeSymlink_() {
done done
shift $((OPTIND - 1)) shift $((OPTIND - 1))
[ ! "$(declare -f "_backupFile_")" ] && fatal "${FUNCNAME[0]} needs function _backupFile_" declare -f _execute_ &>/dev/null || fatal "${FUNCNAME[0]} needs function _execute_"
[ ! "$(declare -f "_execute_")" ] && fatal "${FUNCNAME[0]} needs function _execute_" declare -f _backupFile_ &>/dev/null || fatal "${FUNCNAME[0]} needs function _backupFile_"
if ! command -v realpath >/dev/null 2>&1; then if ! command -v realpath >/dev/null 2>&1; then
error "We must have 'realpath' installed and available in \$PATH to run." error "We must have 'realpath' installed and available in \$PATH to run."
if [[ $OSTYPE == "darwin"* ]]; then if [[ ${OSTYPE} == "darwin"* ]]; then
notice "Install coreutils using homebrew and rerun this script." notice "Install coreutils using homebrew and rerun this script."
info "\t$ brew install coreutils" info "\t$ brew install coreutils"
fi fi
@@ -571,10 +564,10 @@ _makeSymlink_() {
local _originalFile local _originalFile
# Fix files where $HOME is written as '~' # Fix files where $HOME is written as '~'
_destinationFile="${_destinationFile/\~/$HOME}" _destinationFile="${_destinationFile/\~/${HOME}}"
_sourceFile="${_sourceFile/\~/$HOME}" _sourceFile="${_sourceFile/\~/${HOME}}"
[ ! -e "$_sourceFile" ] \ [ ! -e "${_sourceFile}" ] \
&& { && {
error "'${_sourceFile}' not found" error "'${_sourceFile}' not found"
return 1 return 1
@@ -595,9 +588,9 @@ _makeSymlink_() {
_originalFile="$(realpath "${_destinationFile}")" _originalFile="$(realpath "${_destinationFile}")"
[[ ${_originalFile} == "${_sourceFile}" ]] && { [[ ${_originalFile} == "${_sourceFile}" ]] && {
if [ ${_onlyShowChanged} == true ]; then if [[ ${_onlyShowChanged} == true ]]; then
debug "Symlink already exists: ${_sourceFile}${_destinationFile}" debug "Symlink already exists: ${_sourceFile}${_destinationFile}"
elif [ "${DRYRUN}" == true ]; then elif [[ ${DRYRUN:-} == true ]]; then
dryrun "Symlink already exists: ${_sourceFile}${_destinationFile}" dryrun "Symlink already exists: ${_sourceFile}${_destinationFile}"
else else
info "Symlink already exists: ${_sourceFile}${_destinationFile}" info "Symlink already exists: ${_sourceFile}${_destinationFile}"
@@ -693,7 +686,7 @@ _readFile_() {
local _result local _result
local _fileToRead="$1" local _fileToRead="$1"
[ ! -f "$_fileToRead" ] \ [ ! -f "${_fileToRead}" ] \
&& { && {
error "'${_fileToRead}' not found" error "'${_fileToRead}' not found"
return 1 return 1

View File

@@ -62,10 +62,8 @@ _useGNUutils_() {
# NOTES: # NOTES:
# GNU utilities can be added to MacOS using Homebrew # GNU utilities can be added to MacOS using Homebrew
[ ! "$(declare -f "_setPATH_")" ] && fatal "${FUNCNAME[0]} needs function _setPATH_" ! declare -f "_setPATH_" &>/dev/null && fatal "${FUNCNAME[0]} needs function _setPATH_"
[ ! "$(declare -f "_detectOS_")" ] && fatal "${FUNCNAME[0]} needs function _detectOS_"
if [[ $(_detectOS_) == mac ]]; then
if _setPATH_ \ if _setPATH_ \
"/usr/local/opt/gnu-tar/libexec/gnubin" \ "/usr/local/opt/gnu-tar/libexec/gnubin" \
"/usr/local/opt/coreutils/libexec/gnubin" \ "/usr/local/opt/coreutils/libexec/gnubin" \
@@ -75,8 +73,5 @@ _useGNUutils_() {
else else
return 1 return 1
fi fi
else
# Always return 0 on non-MacOS
return 0
fi
} }

View File

@@ -71,7 +71,7 @@ _detectLinuxDistro_() {
local _distro local _distro
if [[ -f /etc/os-release ]]; then if [[ -f /etc/os-release ]]; then
# shellcheck disable=SC1091 # shellcheck disable=SC1091,SC2154
. "/etc/os-release" . "/etc/os-release"
_distro="${NAME}" _distro="${NAME}"
elif type lsb_release >/dev/null 2>&1; then elif type lsb_release >/dev/null 2>&1; then
@@ -79,7 +79,7 @@ _detectLinuxDistro_() {
_distro=$(lsb_release -si) _distro=$(lsb_release -si)
elif [[ -f /etc/lsb-release ]]; then elif [[ -f /etc/lsb-release ]]; then
# For some versions of Debian/Ubuntu without lsb_release command # For some versions of Debian/Ubuntu without lsb_release command
# shellcheck disable=SC1091 # shellcheck disable=SC1091,SC2154
. /etc/lsb-release . /etc/lsb-release
_distro="${DISTRIB_ID}" _distro="${DISTRIB_ID}"
elif [[ -f /etc/debian_version ]]; then elif [[ -f /etc/debian_version ]]; then
@@ -111,7 +111,7 @@ _detectMacOSVersion_() {
# CREDIT: # CREDIT:
# https://github.com/labbots/bash-utility # https://github.com/labbots/bash-utility
[ ! "$(declare -f "_detectOS_")" ] && fatal "${FUNCNAME[0]} needs function _detectOS_" declare -f _detectOS_ &>/dev/null || fatal "${FUNCNAME[0]} needs function _detectOS_"
if [[ "$(_detectOS_)" == "mac" ]]; then if [[ "$(_detectOS_)" == "mac" ]]; then
local _mac_version local _mac_version
@@ -198,7 +198,7 @@ _execute_() {
local OPTIND=1 local OPTIND=1
while getopts ":vVpPeEsSqQnN" opt; do while getopts ":vVpPeEsSqQnN" opt; do
case $opt in case ${opt} in
v | V) _localVerbose=true ;; v | V) _localVerbose=true ;;
p | P) _passFailures=true ;; p | P) _passFailures=true ;;
e | E) _echoResult=true ;; e | E) _echoResult=true ;;
@@ -225,7 +225,7 @@ _execute_() {
VERBOSE=true VERBOSE=true
fi fi
if "${DRYRUN}"; then if "${DRYRUN:-}"; then
if "${_quietMode}"; then if "${_quietMode}"; then
VERBOSE=${_saveVerbose} VERBOSE=${_saveVerbose}
return 0 return 0
@@ -235,7 +235,7 @@ _execute_() {
else else
dryrun "${1}" "$(caller)" dryrun "${1}" "$(caller)"
fi fi
elif ${VERBOSE}; then elif ${VERBOSE:-}; then
if eval "${_command}"; then if eval "${_command}"; then
if "${_quietMode}"; then if "${_quietMode}"; then
VERBOSE=${_saveVerbose} VERBOSE=${_saveVerbose}
@@ -274,7 +274,7 @@ _execute_() {
fi fi
else else
if "${_quietMode}"; then if "${_quietMode}"; then
VERBOSE=$_saveVerbose VERBOSE=${_saveVerbose}
elif "${_echoResult}"; then elif "${_echoResult}"; then
printf "%s\n" "error: ${_executeMessage}" printf "%s\n" "error: ${_executeMessage}"
else else
@@ -303,9 +303,11 @@ _findBaseDir_() {
local _dir local _dir
# Is file sourced? # Is file sourced?
[[ $_ != "$0" ]] \ if [[ ${_} != "${0}" ]]; then
&& _source="${BASH_SOURCE[1]}" \ _source="${BASH_SOURCE[1]}"
|| _source="${BASH_SOURCE[0]}" else
_source="${BASH_SOURCE[0]}"
fi
while [ -h "${_source}" ]; do # Resolve $SOURCE until the file is no longer a symlink while [ -h "${_source}" ]; do # Resolve $SOURCE until the file is no longer a symlink
_dir="$(cd -P "$(dirname "${_source}")" && pwd)" _dir="$(cd -P "$(dirname "${_source}")" && pwd)"
@@ -337,9 +339,9 @@ _generateUUID_() {
for ((n = 0; n < 16; ++n)); do for ((n = 0; n < 16; ++n)); do
_b="$((RANDOM % 256))" _b="$((RANDOM % 256))"
case "$n" in case "${n}" in
6) printf '4%x' "$((_b % 16))" ;; 6) printf '4%x' "$((_b % 16))" ;;
8) printf '%c%x' "${_c:$RANDOM%${#_c}:1}" "$((_b % 16))" ;; 8) printf '%c%x' "${_c:${RANDOM}%${#_c}:1}" "$((_b % 16))" ;;
3 | 5 | 7 | 9) 3 | 5 | 7 | 9)
printf '%02x-' "${_b}" printf '%02x-' "${_b}"
@@ -368,8 +370,8 @@ _makeProgressBar_() {
# done # done
[[ $# == 0 ]] && return # Do nothing if no arguments are passed [[ $# == 0 ]] && return # Do nothing if no arguments are passed
(${QUIET}) && return (${QUIET:-}) && return
(${VERBOSE}) && return (${VERBOSE:-}) && return
[ ! -t 1 ] && return # Do nothing if the output is not a terminal [ ! -t 1 ] && return # Do nothing if the output is not a terminal
[[ ${1} == 1 ]] && return # Do nothing with a single element [[ ${1} == 1 ]] && return # Do nothing with a single element
@@ -390,7 +392,7 @@ _makeProgressBar_() {
tput civis # Hide the cursor tput civis # Hide the cursor
trap 'tput cnorm; exit 1' SIGINT trap 'tput cnorm; exit 1' SIGINT
if [[ ! ${progressBarProgress} -eq $n ]]; then if [[ ! ${progressBarProgress} -eq ${n} ]]; then
#echo "progressBarProgress: $progressBarProgress" #echo "progressBarProgress: $progressBarProgress"
# Compute the percentage. # Compute the percentage.
_percentage=$((progressBarProgress * 100 / $1)) _percentage=$((progressBarProgress * 100 / $1))
@@ -398,8 +400,8 @@ _makeProgressBar_() {
_num=$((progressBarProgress * _width / $1)) _num=$((progressBarProgress * _width / $1))
# Create the progress bar string. # Create the progress bar string.
_bar="" _bar=""
if [ ${_num} -gt 0 ]; then if [[ ${_num} -gt 0 ]]; then
_bar=$(printf "%0.s${_barCharacter}" $(seq 1 ${_num})) _bar=$(printf "%0.s${_barCharacter}" $(seq 1 "${_num}"))
fi fi
# Print the progress bar. # Print the progress bar.
_progressBarLine=$(printf "%s [%-${_width}s] (%d%%)" " ${_barTitle}" "${_bar}" "${_percentage}") _progressBarLine=$(printf "%s [%-${_width}s] (%d%%)" " ${_barTitle}" "${_bar}" "${_percentage}")
@@ -465,7 +467,7 @@ _seekConfirmation_() {
local _yesNo local _yesNo
input "${1}" input "${1}"
if "${FORCE}"; then if "${FORCE:-}"; then
debug "Forcing confirmation with '--force' flag set" debug "Forcing confirmation with '--force' flag set"
printf "%s\n" " " printf "%s\n" " "
return 0 return 0

View File

@@ -42,7 +42,7 @@ _httpStatus_() {
--no-keepalive "${_curlops}" --output /dev/null "${_url}") --no-keepalive "${_curlops}" --output /dev/null "${_url}")
# __________ get the STATUS (from code) which is human interpretable: # __________ get the STATUS (from code) which is human interpretable:
case $_code in case ${_code} in
000) _status="Not responding within ${_timeout} seconds" ;; 000) _status="Not responding within ${_timeout} seconds" ;;
100) _status="Informational: Continue" ;; 100) _status="Informational: Continue" ;;
101) _status="Informational: Switching Protocols" ;; 101) _status="Informational: Switching Protocols" ;;

View File

@@ -35,7 +35,7 @@ _cleanString_() {
local OPTIND=1 local OPTIND=1
while getopts ":lLuUaAsSpP" opt; do while getopts ":lLuUaAsSpP" opt; do
case $opt in case ${opt} in
l | L) _lc=true ;; l | L) _lc=true ;;
u | U) _uc=true ;; u | U) _uc=true ;;
a | A) _alphanumeric=true ;; a | A) _alphanumeric=true ;;
@@ -69,8 +69,8 @@ _cleanString_() {
local i local i
for i in "${_arrayToClean[@]}"; do for i in "${_arrayToClean[@]}"; do
debug "cleaning: $i" debug "cleaning: ${i}"
_string="$(printf "%s" "${_string}" | sed "s/$i//g")" _string="$(printf "%s" "${_string}" | sed "s/${i}//g")"
done done
("${_lc}") \ ("${_lc}") \
@@ -258,7 +258,7 @@ _regexCapture_() {
case ${opt} in case ${opt} in
i | I) i | I)
#shellcheck disable=SC2064 #shellcheck disable=SC2064
trap "$(shopt -p nocasematch)" RETURN # reset nocasematch when function exits trap '$(shopt -p nocasematch)' RETURN # reset nocasematch when function exits
shopt -s nocasematch # Use case-insensitive regex shopt -s nocasematch # Use case-insensitive regex
;; ;;
*) fatal "Unrecognized option '${1}' passed to ${FUNCNAME[0]}. Exiting." ;; *) fatal "Unrecognized option '${1}' passed to ${FUNCNAME[0]}. Exiting." ;;
@@ -332,7 +332,7 @@ _stringContains_() {
case ${opt} in case ${opt} in
i | I) i | I)
#shellcheck disable=SC2064 #shellcheck disable=SC2064
trap "$(shopt -p nocasematch)" RETURN # reset nocasematch when function exits trap '$(shopt -p nocasematch)' RETURN # reset nocasematch when function exits
shopt -s nocasematch # Use case-insensitive searching shopt -s nocasematch # Use case-insensitive searching
;; ;;
*) fatal "Unrecognized option '${1}' passed to ${FUNCNAME[0]}. Exiting." ;; *) fatal "Unrecognized option '${1}' passed to ${FUNCNAME[0]}. Exiting." ;;
@@ -370,7 +370,7 @@ _stringRegex_() {
case ${opt} in case ${opt} in
i | I) i | I)
#shellcheck disable=SC2064 #shellcheck disable=SC2064
trap "$(shopt -p nocasematch)" RETURN # reset nocasematch when function exits trap '$(shopt -p nocasematch)' RETURN # reset nocasematch when function exits
shopt -s nocasematch # Use case-insensitive regex shopt -s nocasematch # Use case-insensitive regex
;; ;;
*) fatal "Unrecognized option '${1}' passed to ${FUNCNAME[0]}. Exiting." ;; *) fatal "Unrecognized option '${1}' passed to ${FUNCNAME[0]}. Exiting." ;;

View File

@@ -1,6 +1,7 @@
# Functions required to allow the script template and alert functions to be used # Functions required to allow the script template and alert functions to be used
# shellcheck disable=SC2154 # shellcheck disable=SC2154
# shellcheck disable=SC2120
_acquireScriptLock_() { _acquireScriptLock_() {
# DESC: # DESC:
# Acquire script lock to prevent running the same script a second time before the # Acquire script lock to prevent running the same script a second time before the
@@ -17,18 +18,18 @@ _acquireScriptLock_() {
if [[ ${1:-} == 'system' ]]; then if [[ ${1:-} == 'system' ]]; then
_lockDir="${TMPDIR:-/tmp/}$(basename "$0").lock" _lockDir="${TMPDIR:-/tmp/}$(basename "$0").lock"
else else
_lockDir="${TMPDIR:-/tmp/}$(basename "$0").$UID.lock" _lockDir="${TMPDIR:-/tmp/}$(basename "$0").${UID}.lock"
fi fi
if command mkdir "${LOCK_DIR}" 2>/dev/null; then if command mkdir "${_lockDir}" 2>/dev/null; then
readonly SCRIPT_LOCK="${_lockDir}" readonly SCRIPT_LOCK="${_lockDir}"
debug "Acquired script lock: ${tan}${SCRIPT_LOCK}${purple}" debug "Acquired script lock: ${yellow}${SCRIPT_LOCK}${purple}"
else else
if [ "$(declare -f "_safeExit_")" ]; then if declare -f "_safeExit_" &>/dev/null; then
error "Unable to acquire script lock: ${yellow}${LOCK_DIR}${red}" error "Unable to acquire script lock: ${yellow}${_lockDir}${red}"
fatal "If you trust the script isn't running, delete the lock dir" fatal "If you trust the script isn't running, delete the lock dir"
else else
printf "%s\n" "ERROR: Could not acquire script lock. If you trust the script isn't running, delete: ${LOCK_DIR}" printf "%s\n" "ERROR: Could not acquire script lock. If you trust the script isn't running, delete: ${_lockDir}"
exit 1 exit 1
fi fi
@@ -70,7 +71,7 @@ _safeExit_() {
if command rm -rf "${SCRIPT_LOCK}"; then if command rm -rf "${SCRIPT_LOCK}"; then
debug "Removing script lock" debug "Removing script lock"
else else
warning "Script lock could not be removed. Try manually deleting ${tan}'${LOCK_DIR}'" warning "Script lock could not be removed. Try manually deleting ${yellow}'${SCRIPT_LOCK}'"
fi fi
fi fi