From bbbac7108c9a144b887ece6e922d2a0f8c0bfa2d Mon Sep 17 00:00:00 2001 From: Patrick Neumann Date: Fri, 15 Jun 2018 12:02:34 +0200 Subject: [PATCH] added my own library --- casualscripter_functions.sh | 300 ++++++++++++++++++++++++++++++++++++ 1 file changed, 300 insertions(+) create mode 100644 casualscripter_functions.sh diff --git a/casualscripter_functions.sh b/casualscripter_functions.sh new file mode 100644 index 0000000..8636dcb --- /dev/null +++ b/casualscripter_functions.sh @@ -0,0 +1,300 @@ +#!/bin/bash +#=============================================================================== +# +# DIRECTORY: +# --- +# +# FILE: +# ./casualscripter_functions.sh +# +# USAGE: +# This is a library for some scripts. +# +# OPTIONS: +# none +# +# EXIT STATES: +# 101 = logfile not set +# 102 = dir for logfile not writable +# 103 = logfile already exists but is not writable +# 104 = a wanted binary is not installed +# +# DESCRIPTION: +# Global configuration and functions for scripts. +# +# REQUIREMENTS: +# which, uname, basename, ps, grep, awk, sed, dirname, tee, openssl, ... +# +# BUGS: +# --- +# +# NOTES: +# Tested on: +# - Debian GNU/Linux 8.x + bash, zsh, ksh, busybox ash & dash +# - ArchLinux + bash, zsh, ksh, busybox ash & dash +# - Linux Mint 18 (Cinnamon) + bash, zsh, ksh, busybox ash & dash +# - FreeBSD 11 + bash, zsh & busybox ash +# - OS X (10.11.6) + bash (sh) and zsh +# ! (t)csh is NOT supported ! +# +# AUTHOR: +# Patrick Neumann, patrick@neumannsland.de +# +# COMPANY: +# (privately) +# +# VERSION: +# 1.0 +# +# LINK TO THE MOST CURRENT VERSION: +# (Sorry, I bet, I'm not allowed to publish it over GitHub!) +# +# CREATED: +# 2016-10-18 +# +# COPYRIGHT (C): +# 2016 - Patrick Neumann +# +# LICENSE: +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# WARRANTY: +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# +# NOTE: +# --- +# +# TODO: +# --- +# +# HISTORY: +# 1.0 - Patrick Neumann - Initial (for the trainers eyes only) release +# +#=============================================================================== + +# Relative paths are more portable but less secure. +# Absolute paths are more secure but less portable. +readonly BIN_WHICH="$( which "which" )" +readonly BIN_UNAME="$( ${BIN_WHICH} "uname" )" +readonly BIN_BASENAME="$( ${BIN_WHICH} "basename" )" +readonly BIN_PS="$( ${BIN_WHICH} "ps" )" +readonly BIN_GREP="$( ${BIN_WHICH} "grep" )" +readonly BIN_AWK="$( ${BIN_WHICH} "awk" )" +readonly BIN_SED="$( ${BIN_WHICH} "sed" )" +readonly BIN_DIRNAME="$( ${BIN_WHICH} "dirname" )" +readonly BIN_TEE="$( ${BIN_WHICH} "tee" )" +readonly BIN_OPENSSL="$( ${BIN_WHICH} "openssl" )" + +# Changeable defaults: +DEFAULT_SHELL="bash" +ECHO_FUNC="display" + +#------------------------------------------------------------------------------- +# Detect operating system name. +#------------------------------------------------------------------------------- +readonly OS_NAME="$( ${BIN_UNAME} -s )" +# "sed -E" on macOS is the same as "sed -r" on Linux +if [ "${OS_NAME}" = "Darwin" -o "${OS_NAME}" = "FreeBSD" ] ; then + readonly SED_EXT_REGEXP="-E" + readonly DATE_DISPLAY="-j -f %s " + readonly DARWIN_FIND_REGEXP_TYPE="-E " +else + readonly SED_EXT_REGEXP="--regexp-extended" + readonly DATE_DISPLAY="-d @" + readonly LINUX_FIND_REGEXP_TYPE="-regextype posix-extended " +fi + +#------------------------------------------------------------------------------- +# Detect the shell in which we are running. +#------------------------------------------------------------------------------- +readonly PROCESS="$( ${BIN_BASENAME} "$( ${BIN_PS} -axco pid,command \ + | ${BIN_GREP} "$$" \ + | ${BIN_GREP} -v "grep" \ + | ${BIN_AWK} '{ print $2; }' )" )" +# Why conditinal command should be prefered over test: +# https://google-styleguide.googlecode.com/svn/trunk/shell.xml#Test,_[_and_[[ +# and why you don't, if you would support "dash": +# http://mywiki.wooledge.org/Bashism +if [ "${PROCESS}" = "$( ${BIN_BASENAME} "${0}" )" ] ; then + readonly CURRENT_SHELL="${DEFAULT_SHELL}" +else + readonly CURRENT_SHELL="${PROCESS}" +fi + +# Linux can have alle shells and "/bin/echo" has no limitations. +# Darwin (14.5.0) has bash 3.2.57, zsh 5.0.5, ksh 93 and tcsh 6.17.00 +# - kshs and tcshs builtin echo does not support "-e" and/or "-n"! +# - "/bin/echo" does not support "-e"! +# FreeBSD can have all shells, but "/bin/echo" has the same limitations! +# Solution: use printf instead! +# Worth readable Link: http://hyperpolyglot.org/unix-shells#echo-note +if [ "${CURRENT_SHELL}" = "zsh" ] ; then + # zsh does not split a string into words separated by spaces by default! + setopt shwordsplit + # zshs "which" find the builtin without "-p"! + readonly BIN_PRINTF="$( which -p printf )" +else + readonly BIN_PRINTF="$( which printf )" +fi + +#=== FUNCTION ================================================================== +# NAME: trim +# DESCRIPTION: Remove leading and trailing whitespace characters from a string. +# PARAMETER 1: string +#------------------------------------------------------------------------------- +# SOMETIMES NEEDED FOR CONFIGURATION! +#=============================================================================== +# Do not use "function" if you want to support dash: +# http://mywiki.wooledge.org/Bashism +trim () { + var="${1}" + var="${var#"${var%%[![:space:]]*}"}" + var="${var%"${var##*[![:space:]]}"}" + ${BIN_PRINTF} "${var}" +} + +#=== FUNCTION ================================================================== +# NAME: logfile_checks +# DESCRIPTION: Checks if a logfile is set and can be created. +# PARAMETERS: none (a global var will be used.) +#=============================================================================== +logfile_checks () { + if [ -z "${LOG_FILE}" ] ; then + ${BIN_PRINTF} "\033[01;31;40mERROR: logfile not set... EXIT!!!\033[00m\n" + exit 101 + fi + if ! [ -w "$( ${BIN_DIRNAME} "${LOG_FILE}" )" ] ; then + ${BIN_PRINTF} "\033[01;31;40mERROR: dir for logfile not writable... EXIT!!!\033[00m\n" + exit 102 + fi + if [ -e "${LOG_FILE}" ] ; then + if ! [ -w "${LOG_FILE}" ] ; then + ${BIN_PRINTF} "\033[01;31;40mERROR: logfile already exists but is not writable... EXIT!!!\033[00m\n" + exit 103 + fi + fi +} + +#=== FUNCTION ================================================================== +# NAME: overwrite +# DESCRIPTION: Check if the custom file already exists and ask for overwriting +# or exit. +# PARAMETER 1: custom file +# PARAMETER 2: file type +#=============================================================================== +overwrite() { + if [ -e "${1}" ] ; then + ${BIN_PRINTF} "\n${2} does already exist, overwrite? \ +(type YES in UPPER letters and hit return!) : " + read -r answer + if [ "${answer}" != "YES" ] ; then + ${BIN_PRINTF} "\033[01;34;40mHINT: move the old ${2} to a save place and try again... EXIT!!!\033[00m\n" + exit 0 + fi + # clear logfile + ${BIN_PRINTF} "" > "${LOG_FILE}" + fi +} + +#=== FUNCTION ================================================================== +# NAME: display +# DESCRIPTION: Wrapper for "echo -n -e". +# PARAMETER 1: message (string) +#=============================================================================== +display () { + ${BIN_PRINTF} "${1}" +} + +#=== FUNCTION ================================================================== +# NAME: log +# DESCRIPTION: Wrapper for "echo -n -e" incl. redirection into logfile. +# PARAMETER 1: message (string) +#=============================================================================== +log () { + logfile_checks + ${BIN_PRINTF} "${1}" >> "${LOG_FILE}" +} + +#=== FUNCTION ================================================================== +# NAME: display_and_log +# DESCRIPTION: Wrapper for "echo -n -e" incl. output to stdout AND redirection +# into logfile. +# PARAMETER 1: message (string) +#=============================================================================== +display_and_log () { + logfile_checks + ${BIN_PRINTF} "${1}" | ${BIN_TEE} -a "${LOG_FILE}" +} + +#=== FUNCTION ================================================================== +# NAME: quiet +# DESCRIPTION: Wrapper for "echo -n -e" incl. redirection into "nirvana". +# PARAMETER 1: message (string) +#=============================================================================== +quiet () { + ${BIN_PRINTF} "${1}" > /dev/null +} + +#=== FUNCTION ================================================================== +# NAME: error +# DESCRIPTION: Display red error messages starting with "ERROR:". +# PARAMETER 1: message (string) +#=============================================================================== +error () { + # TODO: stderr!? + "${ECHO_FUNC}" "\033[01;31;40mERROR: ${1}!!!\033[00m\n" +} + +#=== FUNCTION ================================================================== +# NAME: hint +# DESCRIPTION: Display blue hint messages starting with "HINT:". +# PARAMETER 1: message (string) +#=============================================================================== +hint () { + "${ECHO_FUNC}" "\033[01;34;40mHINT: ${1}!\033[00m\n" +} + +#=== FUNCTION ================================================================== +# NAME: success +# DESCRIPTION: Display green success messages starting with "SUCCESS:". +# PARAMETER 1: message (string) +#=============================================================================== +success () { + "${ECHO_FUNC}" "\033[01;32;40mSUCCESS: ${1}!\033[00m\n" +} + +#=== FUNCTION ================================================================== +# NAME: assign_binary +# DESCRIPTION: ... +# PARAMETER 1: string +#=============================================================================== +assign_binary () { + if [ ${1:0:1} = "/" ] ; then + # Absolute paths are more secure but less portable. + if ! [ -e "${1}" ] ; then + error "${1} not installed" + exit 104 + fi + local var="BIN_$( ${BIN_PRINTF} "$( ${BIN_BASENAME} "${1}" )" | tr [:lower:] [:upper:] )" + eval "readonly $var=\${1}" + else + # Relative paths are more portable but less secure. + local var="BIN_$( ${BIN_PRINTF} "${1}" | tr [:lower:] [:upper:] )" + eval "readonly $var=\$( ${BIN_WHICH} "${1}" )" + if [ -z "$( eval "${BIN_PRINTF} \$$var" )" ] ; then + error "${1} not installed" + exit 104 + fi + fi +} + +# Do not use "exit" at the end of a library!