mirror of
https://github.com/Pmodules/Pmodules.git
synced 2026-06-27 18:13:08 +02:00
303 lines
6.8 KiB
Bash
303 lines
6.8 KiB
Bash
#!/bin/bash
|
|
|
|
#
|
|
# logging/message functions
|
|
#
|
|
std::log() {
|
|
local -ri fd=$1
|
|
local -r fmt="$2"
|
|
shift 2
|
|
printf -- "${fmt}" "$@" 1>&$fd
|
|
printf -- "\n" 1>&$fd
|
|
}
|
|
|
|
std::info() {
|
|
std::log 2 "$1" "${@:2}"
|
|
}
|
|
|
|
std::error() {
|
|
std::log 2 "$1" "${@:2}"
|
|
}
|
|
|
|
std::debug() {
|
|
[[ ${PMODULES_DEBUG} ]] || return 0
|
|
std::log 2 "$@"
|
|
}
|
|
|
|
std::die() {
|
|
local -ri ec=$1
|
|
shift
|
|
if [[ -n $@ ]]; then
|
|
local -r fmt=$1
|
|
shift
|
|
std::log 2 "$fmt" "$@"
|
|
fi
|
|
exit $ec
|
|
}
|
|
|
|
std::def_cmds(){
|
|
local path="$1"
|
|
shift
|
|
for cmd in "$@"; do
|
|
eval declare -g ${cmd}=$(PATH="${path}" which $cmd 2>/dev/null)
|
|
if [[ -z "${!cmd}" ]]; then
|
|
std::die 255 "${cmd} not found"
|
|
fi
|
|
done
|
|
}
|
|
|
|
#
|
|
# get answer to yes/no question
|
|
#
|
|
# $1: prompt
|
|
#
|
|
std::get_YN_answer() {
|
|
local -r prompt="$1"
|
|
local ans
|
|
read -p "${prompt}" ans
|
|
case ${ans} in
|
|
y|Y )
|
|
return 0;;
|
|
* )
|
|
return 1;;
|
|
esac
|
|
}
|
|
|
|
#
|
|
# return normalized abolute pathname
|
|
# $1: filename
|
|
std::get_abspath() {
|
|
local -r fname=$1
|
|
#[[ -r "${fname}" ]] || return 1
|
|
if [[ -d ${fname} ]]; then
|
|
echo $(cd "${fname}" && pwd)
|
|
else
|
|
local -r dname=$(dirname "${fname}")
|
|
echo $(cd "${dname}" && pwd)/$(basename "${fname}")
|
|
fi
|
|
}
|
|
|
|
std::append_path () {
|
|
local -r P=$1
|
|
local -r d=$2
|
|
|
|
if ! echo ${!P} | egrep -q "(^|:)${d}($|:)" ; then
|
|
if [[ -z ${!P} ]]; then
|
|
export "$P=${d}"
|
|
else
|
|
export "$P=${!P}:${d}"
|
|
fi
|
|
fi
|
|
}
|
|
|
|
std::prepend_path () {
|
|
local -r P=$1
|
|
local -r d=$2
|
|
|
|
if ! echo ${!P} | egrep -q "(^|:)${d}($|:)" ; then
|
|
if [[ -z ${!P} ]]; then
|
|
export "$P=${d}"
|
|
else
|
|
export "$P=${d}:${!P}"
|
|
fi
|
|
fi
|
|
}
|
|
|
|
std::remove_path() {
|
|
local -r P=$1
|
|
local -r d=$2
|
|
local new_path=''
|
|
local -r _P=( ${!P//:/ } )
|
|
# loop over all entries in path
|
|
for entry in "${_P[@]}"; do
|
|
[[ "${entry}" != "${d}" ]] && new_path+=":${entry}"
|
|
done
|
|
# remove leading ':'
|
|
eval ${P}="${new_path:1}"
|
|
}
|
|
|
|
#
|
|
# Replace or remove a directory in a path variable.
|
|
#
|
|
# To remove a dir:
|
|
# std::replace_path PATH <pattern>
|
|
#
|
|
# To replace a dir:
|
|
# std::replace_path PATH <pattern> /replacement/path
|
|
#
|
|
# Args:
|
|
# $1 name of the shell variable to set (e.g. PATH)
|
|
# $2 a grep pattern identifying the element to be removed/replaced
|
|
# $3 the replacement string (use "" for removal)
|
|
#
|
|
# Based on solution published here:
|
|
# https://stackoverflow.com/questions/273909/how-do-i-manipulate-path-elements-in-shell-scripts
|
|
#
|
|
std::replace_path () {
|
|
local -r path="$1"
|
|
local -r removepat="$2"
|
|
local -r replacestr="$3"
|
|
|
|
local -r removestr=$(echo "${!path}" | tr ":" "\n" | grep -m 1 "^$removepat\$")
|
|
export $path="$(echo "${!path}" | tr ":" "\n" | sed "s:^${removestr}\$:${replacestr}:" |
|
|
sed '/^\s*$/d' | tr "\n" ":" | sed -e 's|^:||' -e 's|:$||')"
|
|
}
|
|
|
|
#
|
|
# split an absolute path
|
|
#
|
|
# Args:
|
|
# $1 upvar
|
|
# $2 absolute path
|
|
# $3 opt upvar: number of components
|
|
#
|
|
std::split_abspath() {
|
|
local parts="$1"
|
|
local -r path="$2"
|
|
if [[ "${path:0:1}" == '/' ]]; then
|
|
local -r std__split_path_tmp="${path:1}"
|
|
else
|
|
std::die 255 "Oops: Internal error in '${FUNCNAME[0]}' called by '${FUNCNAME[1]}' }"
|
|
fi
|
|
|
|
IFS='/'
|
|
local std__split_path_result=( ${std__split_path_tmp} )
|
|
unset IFS
|
|
std::upvar ${parts} "${std__split_path_result[@]}"
|
|
if (( $# >= 3 )); then
|
|
# return number of parts
|
|
std::upvar "$3" ${#std__split_path_result[@]}
|
|
fi
|
|
}
|
|
|
|
std::read_versions() {
|
|
local -r fname="$1"
|
|
local varname=''
|
|
while read _name _version; do
|
|
[[ -z ${_name} ]] && continue
|
|
[[ -z ${_version} ]] && continue
|
|
[[ "${_name:0:1}" == '#' ]] && continue
|
|
var_name=$(echo ${_name} | tr [:lower:] [:upper:])_VERSION
|
|
# don't set version, if already set
|
|
if [[ -z ${!var_name} ]]; then
|
|
eval ${var_name}="${_version}"
|
|
fi
|
|
done < "${fname}"
|
|
}
|
|
|
|
#--- upvars.sh ---------------------------------------------------------
|
|
# Bash: Passing variables by reference
|
|
# Copyright (C) 2010 Freddy Vulto
|
|
# Version: upvars-0.9.dev
|
|
# See: http://fvue.nl/wiki/Bash:_Passing_variables_by_reference
|
|
#
|
|
# 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.
|
|
#
|
|
# 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 <http://www.gnu.org/licenses/>.
|
|
|
|
|
|
# Assign variable one scope above the caller
|
|
# Usage: local "$1" && upvar $1 "value(s)"
|
|
# Param: $1 Variable name to assign value to
|
|
# Param: $* Value(s) to assign. If multiple values, an array is
|
|
# assigned, otherwise a single value is assigned.
|
|
# NOTE: For assigning multiple variables, use 'upvars'. Do NOT
|
|
# use multiple 'upvar' calls, since one 'upvar' call might
|
|
# reassign a variable to be used by another 'upvar' call.
|
|
# Example:
|
|
#
|
|
# f() { local b; g b; echo $b; }
|
|
# g() { local "$1" && upvar $1 bar; }
|
|
# f # Ok: b=bar
|
|
#
|
|
std::upvar() {
|
|
if unset -v "$1"; then # Unset & validate varname
|
|
if (( $# == 2 )); then
|
|
eval $1=\"\$2\" # Return single value
|
|
else
|
|
eval $1=\(\"\${@:2}\"\) # Return array
|
|
fi
|
|
fi
|
|
}
|
|
|
|
std.get_os_release_linux() {
|
|
local lsb_release=$(which lsb_release)
|
|
local ID=''
|
|
local VERSION_ID=''
|
|
|
|
if [[ -n $(which lsb_release) ]]; then
|
|
ID=$(lsb_release -is)
|
|
VERSION_ID=$(lsb_release -rs)
|
|
elif [[ -r '/etc/os-release' ]]; then
|
|
source /etc/os-release
|
|
else
|
|
std::die 4 "Cannot determin OS release!\n"
|
|
fi
|
|
|
|
case "${ID}" in
|
|
RedHatEnterpriseServer | RedHatEnterprise | Scientific | rhel | centos | CentOS | fedora )
|
|
echo "rhel${VERSION_ID%%.*}"
|
|
;;
|
|
Ubuntu )
|
|
echo "Ubuntu${VERSION_ID%.*}"
|
|
;;
|
|
* )
|
|
echo "Unknown"
|
|
exit 1
|
|
;;
|
|
esac
|
|
}
|
|
std.get_os_release_macos() {
|
|
VERSION_ID=$(sw_vers -productVersion)
|
|
echo "macOS${VERSION_ID%.*}"
|
|
}
|
|
|
|
std::get_os_release() {
|
|
local -A func_map;
|
|
func_map['Linux']=std.get_os_release_linux
|
|
func_map['Darwin']=std.get_os_release_macos
|
|
${func_map[${OS}]}
|
|
}
|
|
|
|
std::get_type() {
|
|
local -a signature=$(typeset -p "$1")
|
|
case ${signature[1]} in
|
|
-Ai* )
|
|
echo 'int dict'
|
|
;;
|
|
-A* )
|
|
echo 'dict'
|
|
;;
|
|
-ai* )
|
|
echo 'int array'
|
|
;;
|
|
-a* )
|
|
echo 'array'
|
|
;;
|
|
-i* )
|
|
echo 'integer'
|
|
;;
|
|
-- )
|
|
echo 'string'
|
|
;;
|
|
* )
|
|
echo 'none'
|
|
return 1
|
|
esac
|
|
}
|
|
|
|
# Local Variables:
|
|
# mode: sh
|
|
# sh-basic-offset: 8
|
|
# tab-width: 8
|
|
# End:
|