Skip to content
Snippets Groups Projects
Commit 6a92646b authored by Brandon Rodriguez's avatar Brandon Rodriguez
Browse files

Initial commit

parents
Branches
No related merge requests found
# Bash - Linux Setup
## Description
Bash script to setup Linux after a fresh install.
run.sh 0 → 100755
#!/usr/bin/env bash
###
# Script to setup Linux after a fresh install.
##
# Abort on error
set -e
# Import utility script.
source $(dirname $0)/utils.sh
###
# Program main.
##
function main () {
run_script_loop=true
# Make sure user is not root user.
check_is_not_user root
# Run program loop.
while [[ $run_script_loop == true ]]
do
echo ""
echo -e "${text_blue}This script provides some quick and easy setup functions for a linux install.${text_reset}"
echo -e "${text_blue}For example, it can map all the \"standard\" user folders to an external drive,${text_reset}"
echo -e "${text_blue}or install the latest version of some very common software.${text_reset}"
echo -e "${text_blue}May not work with all versions of linux.${text_reset}"
echo ""
# Display options.
echo ""
echo -e "${text_blue}Select an option:${text_reset}"
# Get user input.
read user_input
echo ""
echo -e "${text_blue}Exiting program.${text_reset}"
run_script_loop=false
done
echo -e "${text_blue}Terminating script.${text_reset}"
}
main
utils.sh 0 → 100644
#!/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.
#
# https://git.brandon-rodriguez.com/scripts/bash/utils
# Version 1.3.1
##
#region Global Utility Variables.
# Color Output Variables.
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"
# Arg, Kwarg, and Flag Return Variables.
args=()
flags=()
declare -A kwargs=()
global_args=()
global_flags=()
declare -A global_kwargs=()
help_flags=false
# Function Return Variables.
return_value=""
file_name=""
file_extension=""
#endregion Global Utility Variables
#region Script Setup 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.
#
# Return Variable(s): return_value
##
function normalize_terminal () {
cd "$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
}
###
# Handles passed values.
#
# Splits into "args", "kwargs", and "flags":
# * Args are any other values that don't match below two formats.
# * Ex: "True", "5", and "test".
# * Kwargs are key-value pairs, where the key comes first and starts with "--" or "-".
# * Note that the associated value must come immediately after the key.
# * Ex: "--type int", "--dir ./test", and "--name Bob".
# * Flags are any variable that starts with "-" or "--", and must be defined by the calling script.
# * To define flags, populate a "possible_flags" array with flag values prior to calling util script.
# * These are effectively treated as booleans. True if present, false otherwise.
# * Ex: "-a", "--b", "-run", and "--test".
#
# Ordering of provided args, kwargs, and flags should not matter, aside from kwarg keys needing a corresponding value
# as the direct next processed value.
#
# Note that "-h" and "--help" are handled separately, and considered to both be "help flags".
# If either one is provided, then a "help_flags" global variable is set to true.
# The expectation is that some kind of "display help" function will run instead of normal script functionality.
#
# Return Variable(s): help_flags, args, kwargs, flags, global_args, global_kwargs, and global_flags
##
handle_args_kwargs () {
local handle_kwarg=false
local kwarg_key=""
set_global_args=false
set_global_flags=false
set_global_kwargs=false
# On first run, set "global" arg/kwarg values, as backup.
# Useful in case any functions ever call this for additional arg/kwarg/flag handling.
# Prevents original passed values from being overriden by a function's passed values.
if [[ ${#global_args[@]} == 0 && ${#global_flags[@]} == 0 && ${#global_kwargs[@]} == 0 ]]
then
set_global_args=true
set_global_flags=true
set_global_kwargs=true
else
args=()
flags=()
kwargs=()
fi
# Parse all args.
for arg in ${@}
do
# Check arg type, based on substring match.
if [[ "${arg}" == "-h" || "${arg}" == "--help" ]]
then
# Special handling for help flags.
help_flags=true
# Handle for flags.
elif [[ ${#possible_flags[@]} > 0 && ${possible_flags[@]} =~ "${arg}" ]]
then
# Check for kwarg handling bool.
if [[ ${handle_kwarg} == true ]]
then
# Expected arg to fill value for key-value pair. Got flag. Raise error.
echo -e "${text_red}Expected value for kwarg key of \"${kwarg_key}\". Got a flag of \"${arg}\" instead.${text_reset}"
exit 1
else
# Save kwarg key and process next value.
if [[ "${arg}" == "--"* ]]
then
# Handle for double dash flag.
local new_flag=${arg#--}
elif [[ "${arg}" == "-"* ]]
then
# Handle for single dash flag.
local new_flag=${arg#-}
else
# Unexpected kwarg value.
echo -e "${text_red}Unexpected flag type of \"${arg}\". Unable to proceed.${text_reset}"
exit 1
fi
flags+=( ${new_flag} )
# Optionally populate global flags.
if [[ ${set_global_flags} == true ]]
then
global_flags+=( ${new_flag} )
fi
fi
# Handle for kwargs.
elif [[ ("${arg}" == "-"* || "${arg}" == "--"*) && "${arg}" != "---"* ]]
then
# Check for kwarg handling bool.
if [[ ${handle_kwarg} == true ]]
then
# Expected arg to fill value for key-value pair. Got kwarg key. Raise error.
echo -e "${text_red}Expected value for kwarg key of \"${kwarg_key}\". Got another key of \"${arg}\" instead.${text_reset}"
exit 1
else
# Save kwarg key and process next value.
if [[ "${arg}" == "--"* ]]
then
# Handle for two dash kwarg.
kwarg_key=${arg#--}
handle_kwarg=true
elif [[ "${arg}" == "-"* ]]
then
# Handle for one dash kwarg.
kwarg_key=${arg#-}
handle_kwarg=true
else
# Unexpected kwarg value.
echo -e "${text_red}Unexpected kwarg key type of \"${arg}\". Unable to proceed.${text_reset}"
exit 1
fi
fi
# Handle for args.
else
# Check for kwarg handling bool.
if [[ ${handle_kwarg} == true ]]
then
# Set key-value kwarg pair.
kwargs[${kwarg_key}]=${arg}
handle_kwarg=false
# Optionally populate global kwargs.
if [[ ${set_global_kwargs} == true ]]
then
global_kwargs[${kwarg_key}]=${arg}
fi
else
# Add arg to list of args.
args+=( ${arg} )
# Optionally populate global args.
if [[ ${set_global_args} == true ]]
then
global_args+=( ${arg} )
fi
fi
fi
done
}
#endregion Script Setup Functions
#region Directory Functions
###
# Gets absolute path of passed location.
#
# Return Variable(s): return_value
##
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 -P)"
cd ${1}
# Then call this to have consistent symlink handling as files.
return_value="$(cd "$(dirname "$(pwd -P)")"; pwd -P)/$(basename "$(pwd -P)")"
# 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
}
###
# If no arg is provided, returns full path of current directory.
# If arg is passed, then returns absolute path if was directory, or full path of parent directory if was file.
#
# Return Variable(s): return_value
##
function get_directory_path () {
# Check number of passed function args.
if [[ ${#} == 0 ]]
then
# No args passed. Handle for current directory.
get_absolute_path ./
# 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%/*}
elif [[ -d ${1} ]]
then
# Handle for directory.
get_absolute_path ${1}
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 zero or one args, received ${#}.${text_reset}"
exit 1
fi
}
###
# If no arg is provided, then returns name of current directory.
# If arg is passed, then returns name of directory, or parent directory of file.
#
# Return Variable(s): return_value
##
function get_directory_name () {
# Check number of passed function args.
if [[ ${#} == 0 ]]
then
# No args passed. Pass current directory to parent function.
get_directory_path ./
return_value=${return_value##*/}
# Handle for one arg.
elif [[ ${#} == 1 ]]
then
# Pass provided value to parent function.
get_directory_path ${1}
return_value=${return_value##*/}
# Handle for too many args.
else
echo -e "${text_red}Too many args passed. Expected zero or one args, received ${#}.${text_reset}"
exit 1
fi
}
###
# Parses passed file, getting base file name and file extension.
#
# Return Variable(s): return_value
##
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.
#
# Return Variable(s): file_name and 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.
#
# Return Variable(s): None
##
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.
#
# Return Variable(s): None
##
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.
#
# Return Variable(s): return_value
##
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.
#
# Return Variable(s): return_value
##
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
#region Display Functions
###
# Prompts user for yes/no confirmation. Returns True if yes.
# Accepts "yes", "ye", and "y". Input values are treated as case insensitive.
# All other values are treated as "no".
#
# Return Variable(s): return_value
##
function get_user_confirmation () {
# Check number of passed function args.
if [[ ${#} == 0 ]]
then
# Handle prompt for no args passed.
echo -e "[${text_cyan}Yes${text_reset}/${text_cyan}No${text_reset}]"
elif [[ ${#} == 1 ]]
then
# Handle prompt for one arg passed.
echo -e "${1} [${text_cyan}Yes${text_reset}/${text_cyan}No${text_reset}]"
else
# Handle for too many args.
echo -e "${text_red}Too many args passed. Expected zero or one arg, received ${#}.${text_reset}"
exit 1
fi
# Get user input.
read -p " " return_value
echo ""
# Convert input to lower for easy parsing.
to_lower "${return_value}"
# Finally parse user input.
if [[ "${return_value}" == "y" || "${return_value}" == "ye" || "${return_value}" == "yes" ]]
then
# User provided "yes". Return True.
return_value=true
else
# For all other values, return False.
return_value=false
fi
}
###
# Prints out all available text colors provided by this script.
#
# Return Variable(s): None
##
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 ""
}
###
# Prints out all current flags, args, and kwargs, as determined by handle_args_kwargs() function.
# If function has been called multiple times, then will also print out global values.
#
# Return Variable(s): None
##
function display_args_kwargs () {
echo ""
echo -e "${text_blue}Displaying processed flags, args, and kwargs.${text_reset}"
echo ""
# Display for flags.
if [[ ${#flags[@]} > 0: ]]
then
echo -e " ${text_purple}Flags${text_reset} (${#flags[@]} Total):"
echo " ${flags[@]}"
else
echo " No Flags Set."
fi
# Display for args.
if [[ ${#args[@]} > 0 ]]
then
echo -e " ${text_purple}Args${text_reset} (${#args[@]} Total):"
for index in ${!args[@]}
do
echo " ${index}: ${args[${index}]}"
done
else
echo " No Args Set."
fi
# Display for kwargs.
if [[ ${#kwargs[@]} > 0 ]]
then
echo -e " ${text_purple}Kwargs${text_reset} (${#kwargs[@]} Total):"
for key in ${!kwargs[@]}
do
echo " ${key}: ${kwargs[${key}]}"
done
else
echo " No Kwargs Set."
fi
# Only display if global values are different.
if [[ ${flags[@]} != ${global_flags[@]} || ${args[@]} != ${global_args[@]} || ${kwargs[@]} != ${global_kwargs[@]} ]]
then
echo ""
echo ""
# Display for global flags.
if [[ ${#global_flags[@]} > 0: ]]
then
echo -e " ${text_purple}Global Flags${text_reset} (${#global_flags[@]} Total):"
echo " ${global_flags[@]}"
else
echo " No Global Flags Set."
fi
# Display for global args.
if [[ ${#global_args[@]} > 0 ]]
then
echo -e " ${text_purple}Global Args${text_reset} (${#global_args[@]} Total):"
for index in ${!global_args[@]}
do
echo " ${index}: ${global_args[${index}]}"
done
else
echo " No Global Args Set."
fi
# Display for global kwargs.
if [[ ${#global_kwargs[@]} > 0 ]]
then
echo -e " ${text_purple}Global Kwargs${text_reset} (${#global_kwargs[@]} Total):"
for key in ${!global_kwargs[@]}
do
echo " ${key}: ${global_kwargs[${key}]}"
done
else
echo " No Global Kwargs Set."
fi
fi
echo ""
}
#endregion Display Functions
# Functions to call on script import.
normalize_terminal
handle_args_kwargs ${@}
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment