commit 2ac55a57841de3477a41833571052799ea641e54 Author: Scott Duensing Date: Mon May 20 20:02:42 2019 -0500 Initial commit. diff --git a/towel.sh b/towel.sh new file mode 100755 index 0000000..e98a907 --- /dev/null +++ b/towel.sh @@ -0,0 +1,223 @@ +#!/bin/bash -e + +# +# Towel: Randomly Useful Bash Functions +# Never Leave Home Without Your Towel +# +# Copyright (C) 2019 Scott Duensing +# +# This software is provided 'as-is', without any express or implied +# warranty. In no event will the authors be held liable for any damages +# arising from the use of this software. +# +# Permission is granted to anyone to use this software for any purpose, +# including commercial applications, and to alter it and redistribute it +# freely, subject to the following restrictions: +# +# 1. The origin of this software must not be misrepresented; you must not +# claim that you wrote the original software. If you use this software +# in a product, an acknowledgment in the product documentation would be +# appreciated but is not required. +# 2. Altered source versions must be plainly marked as such, and must not be +# misrepresented as being the original software. +# 3. This notice may not be removed or altered from any source distribution. +# + + +# +# Escapes a given string so it's safe to write into an XML document. +# +# Parameters: +# +# RESULT - Variable in which to return the escaped string. +# VAR - String to escape. +# +function tEscapeXml() { + local __RESULT=$1 + local __VAR=${*:2} + + __VAR=$(echo ${__VAR} | sed -e 's~&~\&~g' -e 's~<~\<~g' -e 's~>~\>~g') + + eval $__RESULT=\${__VAR} +} + + +# +# Displays a whiptail-based file browser for selecting a particular type of file. +# +# Parameters: +# +# RESULT - Variable in which to store selected filename, or empty if dialog is canceled. +# TITLE - Title to display in the file browser window. +# EXTENSION - The extension to allow to be selected (in ".ext" format). +# START - Optional. Path to begin browsing from. +# +function tFileBrowser() { + local __RESULT=$1 + local __TITLE=$2 + local __EXTENSION=$3 + local __START=$4 + local __SELECTION= + local __DIRLIST=() + local __CURDIR= + local __RET= + local __LOOPING=1 + + pushd . > /dev/null + + if [[ ! -z ${__START} ]]; then + cd "${__START}" + fi + + while [[ ${__LOOPING} -eq 1 ]]; do + __DIRLIST=() + if [[ "${__CURDIR}" != "/" ]]; then + __DIRLIST[${#__DIRLIST[@]}+1]=".." + __DIRLIST[${#__DIRLIST[@]}+1]="Up" + fi + for F in *; do + if [[ -d "${F}" ]]; then + __DIRLIST[${#__DIRLIST[@]}+1]=$(echo "${F}/ ") + else + __DIRLIST[${#__DIRLIST[@]}+1]=$(echo "${F} ") + fi + __DIRLIST[${#__DIRLIST[@]}+1]=$(ls -lah "${F}" | awk '{ print $5 }') + done + + __CURDIR=$(pwd) + + __SELECTION=$(whiptail --title "${__TITLE}" \ + --menu "PgUp/PgDn/Arrows ENTER Selects File/Folder\nor TAB Key\n\n${__CURDIR}" 0 0 0 \ + --cancel-button "Cancel" \ + --ok-button "Select" "${__DIRLIST[@]}" 3>&1 1>&2 2>&3) + __RET=$? + + if [[ ${__RET} -eq 1 ]]; then + # User Selected Cancel + __SELECTION= + __LOOPING=0 + elif [[ ${__RET} -eq 0 ]]; then + tTrim __SELECTION "${__SELECTION}" + if [[ -d "${__SELECTION}" ]]; then + # Was a directory selected? + cd "${__SELECTION}" + elif [[ -f "${__SELECTION}" ]]; then + # Was a file selected? + if [[ ${__SELECTION} == *${__EXTENSION} ]]; then + # Check if file has given extension + if (whiptail --title "Confirm Selection" \ + --yesno "Directory: ${__CURDIR}\n Filename: ${__SELECTION}" 0 0 \ + --yes-button "Confirm" \ + --no-button "Reselect"); then + __SELECTION="$(pwd)/${__SELECTION}" + __LOOPING=0 + fi + else + # Not requested extension + whiptail --title "Error" \ + --msgbox "Not a ${__EXTENSION} file" 0 0 + fi + else + # Not a file or folder + whiptail --title "Error" \ + --msgbox "Unable to change to directory ${__SELECTION}" 0 0 + fi + fi + done + + eval $__RESULT=\${__SELECTION} + + popd > /dev/null +} + + +# +# Returns the absolute path of a given file. +# +# Parameters: +# +# RESULT - Variable in which to return the absolute path. +# SOURCE - File which we wish to find the absolute path. +# +function tFindPath() { + local __RESULT=$1 + local __SOURCE=$2 + local __DIR= + + while [[ -h "${__SOURCE}" ]]; do + __DIR="$( cd -P "$( dirname "${__SOURCE}" )" && pwd )" + __SOURCE="$(readlink "${__SOURCE}")" + # If $__SOURCE was a relative symlink, we need to resolve it + # relative to the path where the symlink file was located. + [[ ${__SOURCE} != /* ]] && __SOURCE="${__DIR}/${__SOURCE}" + done + __DIR="$( cd -P "$( dirname "${__SOURCE}" )" && pwd )" + + eval $__RESULT=\${__DIR} +} + + +# +# Returns the location and name of the parent script that included us. +# +# Parameters: +# +# RESULT - Variable in which we want the absolute filename returned. +# +function tGetParentPath() { + local __RESULT=$1 + local __PARENTPATH= + + tFindPath __PARENTPATH "${BASH_SOURCE[1]}" + __TOWELPATH="${__PARENTPATH}/`basename \"${BASH_SOURCE[1]}\"`" + + eval $__RESULT=\${__PARENTPATH} +} + + +# +# Returns the location and name of this Towel script. +# +# Parameters: +# +# RESULT - Variable in which we want the absolute filename returned. +# +function tGetTowelPath() { + local __RESULT=$1 + local __TOWELPATH= + + tFindPath __TOWELPATH "${BASH_SOURCE[0]}" + __TOWELPATH="${__TOWELPATH}/`basename \"${BASH_SOURCE[0]}\"`" + + eval $__RESULT=\${__TOWELPATH} +} + + +# +# Removes whitespace from the beginning and end of a string. +# +# Parameters: +# +# RESULT - Variable in which to return the trimmed string. +# VAR - String to trim. +# +function tTrim() { + local __RESULT=$1 + local __VAR="${*:2}" + + # remove leading whitespace characters + __VAR="${__VAR#"${__VAR%%[![:space:]]*}"}" + # remove trailing whitespace characters + __VAR="${__VAR%"${__VAR##*[![:space:]]}"}" + + eval $__RESULT=\${__VAR} +} + + +# +# We're a library. Don't run us. +# +if [ -z "${BASH_SOURCE[1]}" ]; then + echo "This is a library. Include it into other scripts. Don't execute it." + exit 0 +fi