#!/usr/bin/env bash ### # A helper/utility script to be imported by other scripts. # # Intended to hold very common functionality (that's surprisingly not built into bash) such as string upper/lower, # and checking current user value, and prompts of yes/no user input. ## #region Global Utility Variables. # Color Output. text_reset="\033[0m" text_black="\033[0;30m" text_red="\033[0;31m" text_green="\033[0;32m" text_orange="\033[0;33m" text_blue="\033[0;34m" text_purple="\033[0;35m" text_cyan="\033[1;36m" text_yellow="\033[1;33m" text_white="\033[1;37m" # Function Return Variables. return_value="" file_name="" file_extension="" #endregion Global Utility Variables #region Directory Functions ### # Normalizes the location of the terminal to directory of utils.sh file. # # The point is so that the execution of a script will handle the same, regardless of terminal directory location at # script start. Ex: User can start script at either their home folder, or project root, (or any other directory) and # relative directory handling will still function the same in either case. # # Automatically called on script import. ## function normalize_terminal () { cd "$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" } ### # Gets absolute path of passed location. ## function get_absolute_path () { # Check number of passed function args. if [[ ${#} == 1 ]] then # Expected number of args passed. Continue. # Check location type. if [[ -f ${1} ]] then # Handle for file. return_value="$(cd "$(dirname "$1")"; pwd -P)/$(basename "$1")" elif [[ -d ${1} ]] then # Handle for directory. # Extra logic to properly handle values of "./" and "../". local current_dir="$(pwd)" cd ${1} # Then call this to have consistent symlink handling as files. return_value="$(cd "$(dirname "$(pwd)")"; pwd -P)/$(basename "$(pwd)")" # Change back to original location once value is set. cd ${current_dir} else echo -e "${text_red}Passed value ( ${1} ) is not a valid file or directory.${text_reset}" exit 1 fi # Handle for too many args. elif [[ ${#} > 1 ]] then echo -e "${text_red}Too many args passed. Expected one arg, received ${#}.${text_reset}" exit 1 # Handle for too few args. else echo -e "${text_red}Too few args passed. Expected one arg, received 0.${text_reset}" exit 1 fi } ### # Returns name of current directory. # If arg is passed, then returns base name of directory path, or parent directory of file path. ## function get_directory_name () { # Check number of passed function args. if [[ ${#} == 0 ]] then # No args passed. Handle for current directory. return_value=$(pwd) return_value=${return_value##*/} # Handle for one arg. elif [[ ${#} == 1 ]] then # Check location type. if [[ -f ${1} ]] then # Handle for file. get_absolute_path ${1} return_value=${return_value%/*} return_value=${return_value##*/} elif [[ -d ${1} ]] then # Handle for directory. get_absolute_path ${1} return_value=${return_value##*/} else echo -e "${text_red}Passed value ( ${1} ) is not a valid file or directory.${text_reset}" exit 1 fi # Handle for too many args. else echo -e "${text_red}Too many args passed. Expected one arg, received ${#}.${text_reset}" exit 1 fi } ### # Parses passed file, getting base file name and file extension. ## function parse_file_name () { # Check number of passed function args. if [[ ${#} == 1 ]] then # Expected number of args passed. Continue. if [[ -f ${1} ]] then # Handle for file. get_absolute_path ${1} return_value=${return_value##*/} file_name="" file_extension="" _recurse_file_extension ${return_value} else echo -e "${text_red}Passed value ( ${1} ) is not a valid file.${text_reset}" exit 1 fi # Handle for too many args. elif [[ ${#} > 1 ]] then echo -e "${text_red}Too many args passed. Expected one arg, received ${#}.${text_reset}" exit 1 # Handle for too few args. else echo -e "${text_red}Too few args passed. Expected one arg, received 0.${text_reset}" exit 1 fi } ### # Recursive helper function for parse_file_name(). # Determines base file name and full file extension. ## function _recurse_file_extension () { local passed_value=${1} local parsed_extension=${passed_value##*.} # Check if file extension was found. Occurs when variables are not identical. if [[ ${parsed_extension} != ${passed_value} ]] then # Extension found. Iterate once more. file_name=${passed_value%.${parsed_extension}} # Handle if global var is currently empty or not. if [[ ${file_extension} == "" ]] then file_extension=".${parsed_extension}" else file_extension=".${parsed_extension}${file_extension}" fi # Call recursive function once more. _recurse_file_extension ${file_name} fi } #endregion Directory Functions #region User Check Functions ### # Checks if current username matches passed value. # In particular, is used to check if user is sudo/root user. ## function check_is_user () { # Check number of passed function args. if [[ ${#} == 1 ]] then # Expected number of args passed. Continue. local username=$USER local check_user=$1 # Determine user to check for. to_lower ${check_user} if [[ "${return_value}" == "root" || "${return_value}" == "sudo" ]] then # Special logic for checking if "sudo"/"root" user. if [[ "$EUID" != 0 ]] then echo -e "${text_red}Sudo permissions required. Please run as root.${text_reset}" exit fi else # Standard logic for all other user checks. if [[ "${username}" != "${check_user}" ]] then echo -e "${text_red}User check (${check_user}) failed. Current user is ${username}.${text_reset}" exit 1 fi fi # Handle for too many args. elif [[ ${#} > 1 ]] then echo -e "${text_red}Too many args passed. Expected one arg, received ${#}.${text_reset}" exit 1 # Handle for too few args. else echo -e "${text_red}Too few args passed. Expected one arg, received 0.${text_reset}" exit 1 fi } ### # Checks if current username does not match passed value. # In particular, is used to check if user is not sudo/root user. ## function check_is_not_user () { # Check number of passed function args. if [[ ${#} == 1 ]] then # Expected number of args passed. Continue. local username=$USER local check_user=$1 # Determine user to check for. to_lower ${check_user} if [[ "${return_value}" == "root" || "${return_value}" == "sudo" ]] then # Special logic for checking if "sudo"/"root" user. if [[ "$EUID" == 0 ]] then echo -e "${text_red}Standard permissions required. Please run as non-root user.${text_reset}" exit fi else # Standard logic for all other user checks. if [[ "${username}" == "${check_user}" ]] then echo -e "${text_red}Not-user check (${check_user}) failed. Current user is ${username}.${text_reset}" exit 1 fi fi # Handle for too many args. elif [[ ${#} > 1 ]] then echo -e "${text_red}Too many args passed. Expected one arg, received ${#}.${text_reset}" exit 1 # Handle for too few args. else echo -e "${text_red}Too few args passed. Expected one arg, received 0.${text_reset}" exit 1 fi } #endregion User Check Functions #region Text Manipulation Functions ### # Converts one or more passed args to uppercase characters. ## function to_upper () { # Check number of passed function args. if [[ ${#} > 0 ]] then # At least one arg passed. Loop through each one. return_value=() for arg in $@ do return_value+=( $(echo "${arg}" | tr '[:lower:]' '[:upper:]') ) done # No args passed. else echo -e "${text_red}Too few args passed. Expected one arg, received 0.${text_reset}" exit 1 fi } ### # Convers one or more passed args to lowercase characters. ## function to_lower () { # Check number of passed function args. if [[ ${#} > 0 ]] then # At least one arg passed. Loop through each one. return_value=() for arg in ${@} do return_value+=( $(echo "${arg}" | tr '[:upper:]' '[:lower:]') ) done # No args passed. else echo -e "${text_red}Too few args passed. Expected one arg, received 0.${text_reset}" exit 1 fi } #endregion Text Manipulation Functions ### # Prints out all available text colors provided by this script. ## function display_text_colors () { echo "" echo "Displaying all available text colors:" echo -e " ${text_black}Black${text_reset}" echo -e " ${text_red}Red${text_reset}" echo -e " ${text_green}Green${text_reset}" echo -e " ${text_orange}Orange${text_reset}" echo -e " ${text_blue}Blue${text_reset}" echo -e " ${text_purple}Purple${text_reset}" echo -e " ${text_cyan}Cyan${text_reset}" echo -e " ${text_yellow}Yellow${text_reset}" echo -e " ${text_white}White${text_reset}" echo "" } # Functions to call on script import. normalize_terminal