improve module base - use stderr for error messages
helpers: added mkrfilename for making random file names instead of using mktemp remote_arg function escapes spaces within an arugment(s) for use passing remotelymaster
parent
398ae39a07
commit
b7b2d7061a
|
@ -64,3 +64,7 @@ interactive non-login shells source /etc/profile via /etc/bash.bashrc otherwise
|
||||||
|
|
||||||
Thus for non-interactive/non-login shells it is best to symlink a non-module file/directory in modules folder in order to give access to non-interactive shells
|
Thus for non-interactive/non-login shells it is best to symlink a non-module file/directory in modules folder in order to give access to non-interactive shells
|
||||||
|
|
||||||
|
|
||||||
|
TODO
|
||||||
|
|
||||||
|
* conditionally create a `which` function` in shell.env if which command is not availble. which being pretty much the same as `command -v cmd`
|
25
module.base
25
module.base
|
@ -10,15 +10,14 @@ if [ "$FILE" ]; then
|
||||||
COUNT=$(echo $FILE | xargs -n 1 | wc -l)
|
COUNT=$(echo $FILE | xargs -n 1 | wc -l)
|
||||||
fi
|
fi
|
||||||
if [ $COUNT -gt 1 ]; then
|
if [ $COUNT -gt 1 ]; then
|
||||||
echo two or more modules of same name found, aborting
|
>&2 echo two or more modules of same name found, aborting
|
||||||
echo $FILE | xargs -n 1
|
>&2 echo $FILE | xargs -n 1
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
[ $COUNT == 1 ] && echo $FILE && return 0
|
[[ $COUNT == 1 ]] && echo $FILE
|
||||||
return 1
|
|
||||||
}
|
}
|
||||||
module_find() {
|
module_find() {
|
||||||
[ ! $1 ] && echo "no module specified" && return 1
|
[ ! $1 ] && >&2 echo "no module specified" && return 1
|
||||||
local MDIRS
|
local MDIRS
|
||||||
local MDIR
|
local MDIR
|
||||||
local DIRS
|
local DIRS
|
||||||
|
@ -36,17 +35,21 @@ for ((i=1;i<=cnt;i++)); do
|
||||||
[ $? -eq 0 ] && echo $RES && return 0
|
[ $? -eq 0 ] && echo $RES && return 0
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
>&2 echo no module found anywhere
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
}
|
}
|
||||||
module_load() {
|
module_load() {
|
||||||
[ ! $1 ] && echo "no module specified" && return 1
|
local module;local mpath
|
||||||
|
[ ! $1 ] && >&2 echo "no module specified" && return 1
|
||||||
local FILE
|
local FILE
|
||||||
FILE=$(module_find $1)
|
for module in "$@"
|
||||||
[ $? -ne 0 ] && echo no module $1 found && return 1
|
do
|
||||||
shift 1
|
eval "_${module}_ () { echo "$fname test"; }"
|
||||||
source $FILE "$@"
|
mpath=$(module_find $module)
|
||||||
return 0
|
[ $? -ne 0 ] && >&2 echo extreme warning: no module $1 found, so was not loaded
|
||||||
|
source $mpath "$@"
|
||||||
|
done
|
||||||
}
|
}
|
||||||
shell_run () {
|
shell_run () {
|
||||||
bash -ci ". ${1}"
|
bash -ci ". ${1}"
|
||||||
|
|
|
@ -19,20 +19,18 @@ COUNT=0
|
||||||
if [ "$FILE" ]; then
|
if [ "$FILE" ]; then
|
||||||
COUNT=$(echo $FILE | xargs -n 1 | wc -l)
|
COUNT=$(echo $FILE | xargs -n 1 | wc -l)
|
||||||
fi
|
fi
|
||||||
# echo Number: $COUNT
|
|
||||||
if [ $COUNT -gt 1 ]; then
|
if [ $COUNT -gt 1 ]; then
|
||||||
echo two or more modules of same name found, aborting
|
>&2 echo two or more modules of same name found, aborting
|
||||||
echo $FILE | xargs -n 1
|
>&2 echo $FILE | xargs -n 1
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
[ $COUNT == 1 ] && echo $FILE && return 0
|
[[ $COUNT == 1 ]] && echo $FILE
|
||||||
return 1
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# Returns path to module if succesful
|
# Returns path to module if succesful
|
||||||
module_find() {
|
module_find() {
|
||||||
|
|
||||||
[ ! $1 ] && echo "no module specified" && return 1
|
[ ! $1 ] && >&2 echo "no module specified" && return 1
|
||||||
|
|
||||||
local MDIRS
|
local MDIRS
|
||||||
local MDIR
|
local MDIR
|
||||||
|
@ -65,22 +63,28 @@ for ((i=1;i<=cnt;i++)); do
|
||||||
[ $? -eq 0 ] && echo $RES && return 0
|
[ $? -eq 0 ] && echo $RES && return 0
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
# no module found anywhere
|
>&2 echo no module found anywhere
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
module_load() {
|
module_load() {
|
||||||
[ ! $1 ] && echo "no module specified" && return 1
|
local module;local mpath
|
||||||
# (return 0 2>/dev/null) && echo "module_load was sourced" || echo "module_log was executed"
|
[ ! $1 ] && >&2 echo "no module specified" && return 1
|
||||||
local FILE
|
local FILE
|
||||||
FILE=$(module_find $1)
|
for module in "$@"
|
||||||
[ $? -ne 0 ] && echo no module $1 found && return 1
|
do
|
||||||
# source $FILE "$0"
|
# is there way to not reload modules??
|
||||||
# [[ $BASHPID -eq $$ ]] || echo $FILE
|
# if [[ $(eval "echo \"\$MODULE_$module_LOADED\"") ]]; then
|
||||||
shift 1
|
# echo $module already loaded
|
||||||
source $FILE "$@"
|
# else
|
||||||
return 0
|
eval "_${module}_ () { echo "$fname test"; }"
|
||||||
|
mpath=$(module_find $module)
|
||||||
|
[ $? -ne 0 ] && >&2 echo extreme warning: no module $1 found, so was not loaded
|
||||||
|
source $mpath "$@"
|
||||||
|
# eval "MODULE_$module_LOADED=true"
|
||||||
|
# fi
|
||||||
|
done
|
||||||
}
|
}
|
||||||
|
|
||||||
# put here so it's globally available
|
# put here so it's globally available
|
||||||
|
|
|
@ -9,64 +9,69 @@
|
||||||
# source <(echo -e "$scpt")
|
# source <(echo -e "$scpt")
|
||||||
module_load debug
|
module_load debug
|
||||||
module_load file
|
module_load file
|
||||||
|
module_load helpers
|
||||||
|
|
||||||
|
# TODO keep debug statements if requested, other remove them
|
||||||
|
|
||||||
bundle () {
|
bundle () {
|
||||||
|
|
||||||
local file
|
local file; local xfunc; local compact; local func;
|
||||||
local code
|
|
||||||
local compact
|
debug $( ( IFS=$','; echo bundle arguments: "$*" ) )
|
||||||
if [[ $1 == "-c" ]]; then
|
|
||||||
module_load helpers
|
declare OPTION; declare OPTARG; declare OPTIND
|
||||||
compact=true
|
while getopts 'cf:x:' OPTION; do
|
||||||
shift 1
|
case "$OPTION" in
|
||||||
fi
|
c)
|
||||||
|
compact=true
|
||||||
# todo add -c for compacting the bundle, change this to options parsing.
|
;;
|
||||||
|
f)
|
||||||
if [[ "$1" ]]; then
|
# can pass any arguments along with the function to run. Use " " for any argument with spaces
|
||||||
if [[ -f $1 ]]; then
|
func="$OPTARG"
|
||||||
file=$1
|
;;
|
||||||
else
|
x)
|
||||||
if [[ $1 == "-m" ]]; then
|
# will extract a function from a file or module to be used for bundling
|
||||||
file=$(module_find $2)
|
xfunc="$OPTARG"
|
||||||
shift 1
|
;;
|
||||||
else
|
*)
|
||||||
if [[ $1 == "-mf" ]]; then
|
echo unknown bundle option $OPTION
|
||||||
module_load $2
|
;;
|
||||||
code="$(declare -f $3)"
|
esac
|
||||||
shift 1
|
done
|
||||||
else
|
|
||||||
code="$1"
|
shift $(( OPTIND - 1 ))
|
||||||
shift 1
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
echo "aborting, no file, module or function passed for bundling"
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
tmp_file=$( mktemp -t TEMP_FILE_bundle.XXXXXXXX )
|
tmp_file=$( mktemp -t TEMP_FILE_bundle.XXXXXXXX )
|
||||||
chmod 600 "$tmp_file"
|
chmod 600 "$tmp_file"
|
||||||
# if [[ $2 == "__recurse__" ]] || [[ $file ]]; then
|
|
||||||
if [[ $file ]]; then
|
if [[ -f $1 ]]; then file=$1; else
|
||||||
\cp $file $tmp_file
|
if ! file=$(module_find "$1"); then >&2 echo fatal: bundle error, no module of name: $1; file=""; fi; fi
|
||||||
else
|
[[ ! $file ]] && >&2 echo "fatal: bundle error aborting, no file, module passed for bundling" && return 1
|
||||||
echo "$code" > $tmp_file
|
\cp $file $tmp_file
|
||||||
fi
|
if [[ $xfunc ]]; then
|
||||||
|
( source $file; declare -f $xfunc > $tmp_file )
|
||||||
|
fi
|
||||||
|
|
||||||
if [[ ! $2 == "__recurse__" ]]; then
|
if [[ ! $2 == "__recurse__" ]]; then
|
||||||
_modules=""
|
_modules=""
|
||||||
output=$2
|
output=$2
|
||||||
debug outputing bundle to: $output
|
[[ $output ]] && debug outputing bundle to: $output || debug outputting bundle to console
|
||||||
debug "bash code to bundle \n $(cat $tmp_file)"
|
debug "bash code to bundle \n $(cat $tmp_file)"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
modules=$(sed -n -e 's/^\s*module_load //p' < $tmp_file)
|
modules=$(sed -n -e 's/^\s*module_load //p' < $tmp_file)
|
||||||
|
# if [[ ( ! $modules ) && ( ! $2 == "__recurse__" ) ]]; then
|
||||||
|
# if [[ $output ]]; then
|
||||||
|
# \cp $tmp_file $output
|
||||||
|
# else
|
||||||
|
# echo -e "$(cat $tmp_file)"
|
||||||
|
# fi
|
||||||
|
# fi
|
||||||
|
|
||||||
|
# remove debug module by default so it doesn't get bundled
|
||||||
|
|
||||||
if [[ $modules ]]; then
|
if [[ $modules ]]; then
|
||||||
# remove found module_load before continuing
|
# remove all found module_load before continuing
|
||||||
sed -i '/^\s*module_load/d' $tmp_file
|
sed -i '/^\s*module_load/d' $tmp_file
|
||||||
[[ $_modules ]] && debug "already bundled modules: $_modules"
|
[[ $_modules ]] && debug "already bundled modules: $_modules"
|
||||||
for module in $(printf '%s\n' "${modules[@]}"|tac);
|
for module in $(printf '%s\n' "${modules[@]}"|tac);
|
||||||
|
@ -86,14 +91,19 @@ bundle () {
|
||||||
|
|
||||||
# the recursion is done
|
# the recursion is done
|
||||||
if [[ ! $2 == "__recurse__" ]]; then
|
if [[ ! $2 == "__recurse__" ]]; then
|
||||||
[[ $compact ]] && compact_file $tmp_file
|
[[ $compact ]] && compact_file $tmp_file
|
||||||
if [[ $BASH_DEBUG ]]; then
|
# TODO remove debug statements by default
|
||||||
|
# remove any default function calls
|
||||||
|
sed -i '/\s*(\s*return 0 2>\/dev\/null\s*)\s*|| /d' $tmp_file
|
||||||
|
# add in a function call if requested
|
||||||
|
[[ $func ]] && echo -e "\n $func \"\$@\"" >> $tmp_file
|
||||||
|
if [[ $BASH_DEBUG ]]; then
|
||||||
debug "\n ------------code as bundled--------------\n \
|
debug "\n ------------code as bundled--------------\n \
|
||||||
$(cat $tmp_file) \
|
$(cat $tmp_file) \
|
||||||
\n ------------------------------------------------------------ \n"
|
\n ------------------------------------------------------------ \n"
|
||||||
debug "bundled modules were $_modules"
|
debug "bundled modules were $_modules"
|
||||||
fi
|
fi
|
||||||
if [[ $2 ]]; then
|
if [[ $output ]]; then
|
||||||
\cp $tmp_file $output
|
\cp $tmp_file $output
|
||||||
else
|
else
|
||||||
echo -e "$(cat $tmp_file)"
|
echo -e "$(cat $tmp_file)"
|
||||||
|
@ -105,3 +115,5 @@ bundle () {
|
||||||
|
|
||||||
# # if script was executed then call the function
|
# # if script was executed then call the function
|
||||||
(return 0 2>/dev/null) || bundle $@
|
(return 0 2>/dev/null) || bundle $@
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
# TODO allow debug to have managment flags and levels
|
# TODO allow debug to have managment flags and levels
|
||||||
|
# TODO filter debug statements to a particular module
|
||||||
function debug () {
|
function debug () {
|
||||||
|
|
||||||
if [[ $BASH_DEBUG ]]; then
|
if [[ $BASH_DEBUG ]]; then
|
||||||
|
|
|
@ -61,25 +61,50 @@ parse_option () {
|
||||||
# otherwise just the options value
|
# otherwise just the options value
|
||||||
local opts;local f;local opt; local ret
|
local opts;local f;local opt; local ret
|
||||||
[[ $1 = "-f" ]] && { f=true;shift 1; }
|
[[ $1 = "-f" ]] && { f=true;shift 1; }
|
||||||
[[ $1 && $2 ]] || return 1
|
[[ ! $# -eq 2 ]] && return 1
|
||||||
opts=$1
|
opts=$1
|
||||||
opt=$2
|
opt=$2
|
||||||
[[ ! $opts =~ "$opt" ]] && return 1
|
# echo $opts, $opt
|
||||||
ret=$(sed -n "/^.*$opt\s\+\(\w\+\).*$/s//\1/p" <<< $opts)
|
[[ ! $opts =~ $opt ]] && return 1
|
||||||
|
ret=$(sed -n '/^.*'"$opt"'\s\+\(\w\+\).*$/s//\1/p' <<< $opts)
|
||||||
[[ $f ]] && echo "$2 $ret" || echo $ret
|
[[ $f ]] && echo "$2 $ret" || echo $ret
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# TODO: need to pass two arrays and then pass them back, see -r ret in ssh for example
|
||||||
|
# parse_extra_args () {
|
||||||
|
# if [[ ! $* =~ "--" ]]; then
|
||||||
|
# debug $( ( IFS=$','; echo all arguments: "$*" ) )
|
||||||
|
# for ((d=1; d<$#; ++d)); do
|
||||||
|
# [[ ${!d} == "--" ]] && break
|
||||||
|
# done
|
||||||
|
# if [[ $d -lt $# ]]; then # if there are extra ssh arguments
|
||||||
|
# debug found -- at $d
|
||||||
|
# opts=("${@:$d+1:$#}")
|
||||||
|
# debug $( ( IFS=$','; echo "ssh arguments: ${opts[*]}" ) )
|
||||||
|
# # [[ ! ${sshargs[0]} ]] && { echo missing remote machine, must provide at least a hostname, -- hostname; return 3; }
|
||||||
|
# ropts=("${@:1:$d-1}")
|
||||||
|
# debug $( ( IFS=$','; echo "remaining arguments to parse: ${ropts[*]}" ) )
|
||||||
|
# fi
|
||||||
|
# fi
|
||||||
|
# }
|
||||||
|
|
||||||
remove_empty_lines () {
|
remove_empty_lines () {
|
||||||
if [[ -f $1 ]]; then cat $1; else echo "$1"; fi | sed -n '/^\s*$/!p'
|
if [[ -f $1 ]]; then cat $1; else echo "$1"; fi | sed -n '/^\s*$/!p'
|
||||||
# sed -rz 's/^\n+//; s/\n+$/\n/g'
|
# sed -rz 's/^\n+//; s/\n+$/\n/g'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
remote_args () {
|
||||||
|
local rargs
|
||||||
|
for i; do rargs="$rargs $(sed 's/ /\\ /g' <<< $i)"; done
|
||||||
|
echo $rargs
|
||||||
|
}
|
||||||
|
|
||||||
remove_end_spaces () {
|
remove_end_spaces () {
|
||||||
del=${2:-\'}
|
del=${2:-\'}
|
||||||
# echo delimiter: $del
|
# echo delimiter: $del
|
||||||
# sed -e "s/[[:space:]]\{1,\}$del/$del/" <<< "$1"
|
# sed -e 's/[[:space:]]\{1,\}$del/$del/' <<< "$1"
|
||||||
res=$(sed -e "s/^$del[[:space:]]*/$del/" <<< "$1")
|
res=$(sed -e 's/^$del[[:space:]]*/$del/' <<< "$1")
|
||||||
sed -e "s/[[:space:]]*${del}$/$del/" <<< "$res"
|
sed -e 's/[[:space:]]*${del}$/$del/' <<< "$res"
|
||||||
}
|
}
|
||||||
|
|
||||||
# pass any sed ' ' string and comments lines will be ignored
|
# pass any sed ' ' string and comments lines will be ignored
|
||||||
|
@ -102,8 +127,24 @@ compact_file () {
|
||||||
# if [[ -f "$1" ]]; then cat "$1"; else echo -e "$@"; fi | sed 's/\\s*$//g' | sed -r '/^\s*$/d' | grep -v '^\s*#'
|
# if [[ -f "$1" ]]; then cat "$1"; else echo -e "$@"; fi | sed 's/\\s*$//g' | sed -r '/^\s*$/d' | grep -v '^\s*#'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mkrfilename () {
|
||||||
|
echo ${2:-/tmp/}${1:-file}.$RANDOM
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
sshtest () {
|
||||||
|
echo running on machine: $(hostnamectl hostname)
|
||||||
|
echo as user:home $(whoami):$HOME
|
||||||
|
echo argument1 $1
|
||||||
|
echo argument2 $2
|
||||||
|
echo remaining arguments: "${@:3}"
|
||||||
|
echo home directory listing
|
||||||
|
ls -la ~
|
||||||
|
}
|
||||||
|
|
||||||
#rows between matched rows
|
#rows between matched rows
|
||||||
# sed '1,/firstmatch/d;/secondmatch/,$d'
|
# sed '1,/firstmatch/d;/secondmatch/,$d'
|
||||||
|
|
||||||
|
# this will escape ' for all lines having sed
|
||||||
|
# sed -i '/sed/s/\x27/\\'"'"'/g' $tmp_file
|
|
@ -1,6 +1,6 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
iecho () {
|
iecho () {
|
||||||
[[ ! -z "$PS1" ]] && echo $1
|
[[ ! -z "$PS1" ]] && echo "$@"
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue