add i.set and autosave system
Along with various (likely irritating) rearranging of code and adjusting of this and that, this change includes identity a basic setter method for identies along with an autoback system which can be inhibited via `export C4_I_AUTOBACKUP_INHIBIT=1`."
This commit is contained in:
parent
961a3ecec2
commit
352e19c87b
1 changed files with 276 additions and 192 deletions
468
ghostwheel.fn.sh
468
ghostwheel.fn.sh
|
|
@ -51,33 +51,82 @@ C4_T_OKAY="${C4_T_OKAY-OKAY}"
|
||||||
C4_T_FAIL="${C4_T_FAIL-FAIL}"
|
C4_T_FAIL="${C4_T_FAIL-FAIL}"
|
||||||
|
|
||||||
####
|
####
|
||||||
#Lab: this ugly beast merges bash associate arrays
|
## Lab: this ugly beast merges bash associate arrays
|
||||||
# (c=(`unset a b c; \
|
# (c=(`unset a b c; \
|
||||||
# declare -A a=([b]="bb" [c]="cc"); \
|
# declare -A a=([b]="bb" [c]="cc"); \
|
||||||
# declare -A b=([d]="dd"); declare -p a b | \
|
# declare -A b=([d]="dd"); declare -p a b | \
|
||||||
# perl -e '@a= map { chomp; s/^.*=\(|\)$//g; $_ } <>; print qq(@a)' \
|
# perl -e '@a= map { chomp; s/^.*=\(|\)$//g; $_ } <>; print qq(@a)' \
|
||||||
# `); declare -p c)
|
# `); declare -p c)
|
||||||
# declare -A c=(["[c]=\"cc\" [b]=\"bb\" [d]=\"dd\" "]="" )
|
## :Lab declare -A c=(["[c]=\"cc\" [b]=\"bb\" [d]=\"dd\" "]="" )
|
||||||
|
####
|
||||||
|
## Lab: this one can let us pass functions around
|
||||||
|
# (foo="$(declare -fx foo; \
|
||||||
|
# function foo { \
|
||||||
|
# echo hello;\
|
||||||
|
# } ; \
|
||||||
|
# export -pf foo; \
|
||||||
|
# declare -pf foo; \
|
||||||
|
# )" ; \
|
||||||
|
# eval "$foo"; \
|
||||||
|
# foo )
|
||||||
|
## :Lab hello;
|
||||||
####
|
####
|
||||||
|
|
||||||
#### c4.maa -
|
#### c4.f.dval
|
||||||
### join valueset assignments of bash assoicative arrays
|
### output assignments from bash arrays
|
||||||
### (unset a b c; \
|
### (unset a b c; \
|
||||||
### declare -A a=([b]="bb" [c]="cc"); \
|
### declare -A a=([b]="bb" [c]="cc"); \
|
||||||
### declare -A b=([d]="dd");\
|
### declare -A b=([d]="dd");\
|
||||||
### echo $( c4.maa a b ) )
|
### echo $( c4.f.dval a b ) )
|
||||||
function c4.maa {
|
function c4.f.dval {
|
||||||
# avoid warning from declare -p when no arguments are given
|
declare -p $@ | perl -e '
|
||||||
test "$*" && \
|
# combine assignments:
|
||||||
declare -p $@ \
|
$\=q( ); # 1. join ouput on space
|
||||||
| perl -e ' # combine assignments:
|
print map { # 6. output the line
|
||||||
$\=q( ); # 1. join ouput on space
|
chomp; # 3. rm -f newline
|
||||||
print map { # 6. output the line
|
s/^.*=\(|\)$//g; # 4. extract assignments
|
||||||
chomp; # 3. rm -f newline
|
$_ # 5. use value (not replacment count)
|
||||||
s/^.*=\(|\)$//g; # 4. extract assignments
|
} <>' # 2. walk input from declare -p
|
||||||
$_ # 5. use value (not replacment count)
|
}
|
||||||
} <>' # 2. walk input from declare -p
|
#### -END c4.f.dval
|
||||||
} #### -END c4.maa
|
|
||||||
|
|
||||||
|
#### c4.f.prgs_Array -
|
||||||
|
### create associative array from (quoted) name list and args
|
||||||
|
function c4.f.pargs {
|
||||||
|
declare -la rv=()
|
||||||
|
while test -n "$1" ; do
|
||||||
|
rv+=$1; shift
|
||||||
|
done
|
||||||
|
c4.f.dval rv
|
||||||
|
}
|
||||||
|
#### -END c4.f.pargs_Array
|
||||||
|
|
||||||
|
#### c4.f.sargs_Array -
|
||||||
|
### create array from (quoted) string list
|
||||||
|
function c4.f.sargs {
|
||||||
|
local -a rv;
|
||||||
|
local -i i=0;
|
||||||
|
for arg in $1 ; do
|
||||||
|
rv+=$arg;
|
||||||
|
done
|
||||||
|
c4.f.dval rv
|
||||||
|
}
|
||||||
|
#### -END c4.f.sargs
|
||||||
|
|
||||||
|
#### c4.f.nrgs_Array -
|
||||||
|
### create associative array from (quoted) name list and args
|
||||||
|
#(eval "declare -lA v=($( . ghostwheel.fn.sh; c4.f.nargs "a b" "c" "d" ))"; echo "${v[a]}") #c
|
||||||
|
function c4.f.nargs {
|
||||||
|
local names="$1"; shift;
|
||||||
|
local -A rv;
|
||||||
|
local n; for n in $names ; do
|
||||||
|
rv[$n]="$1";
|
||||||
|
shift;
|
||||||
|
done
|
||||||
|
c4.f.dval rv
|
||||||
|
}
|
||||||
|
#### -END c4.f.pargs_Array
|
||||||
|
|
||||||
function c4.t.b {
|
function c4.t.b {
|
||||||
C4_TN=$((++C4_TN))
|
C4_TN=$((++C4_TN))
|
||||||
|
|
@ -86,7 +135,7 @@ function c4.t.b {
|
||||||
[tn]=$C4_TN
|
[tn]=$C4_TN
|
||||||
[okrv]=0 [okay]="$C4_T_OKAY" [fail]="$C4_T_FAIL"
|
[okrv]=0 [okay]="$C4_T_OKAY" [fail]="$C4_T_FAIL"
|
||||||
[tags]="$1" [runl]="$2" [name]="$3" [desc]="$4"
|
[tags]="$1" [runl]="$2" [name]="$3" [desc]="$4"
|
||||||
); shift; shift; shift; shift;
|
); shift 4;
|
||||||
|
|
||||||
# pick the first non-empty tag as a prefix
|
# pick the first non-empty tag as a prefix
|
||||||
for t in ${ta[tags]} ; do
|
for t in ${ta[tags]} ; do
|
||||||
|
|
@ -223,7 +272,7 @@ function c4.s.first {
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
}
|
}
|
||||||
c4.t.b "s" 0 "first" "[ x z] == z" test "x" == '$( c4.s.first "" "$foo" "x" "z" )'
|
c4.t.b "s" 0 "first" "[ x z] == x" test "x" == '$( c4.s.first "" "$foo" "x" "z" )'
|
||||||
|
|
||||||
## Return first non-empty item matching PATTERN from SET
|
## Return first non-empty item matching PATTERN from SET
|
||||||
## when NEGATE is ! or NOT return first non-empty, non-
|
## when NEGATE is ! or NOT return first non-empty, non-
|
||||||
|
|
@ -257,7 +306,7 @@ function c4.s.firstmatch {
|
||||||
done
|
done
|
||||||
}
|
}
|
||||||
c4.t.b "s" 0 "firstmatch" "[x o x] == x" test "x" == '"$( c4.s.firstmatch "x" "o" "x" )"'
|
c4.t.b "s" 0 "firstmatch" "[x o x] == x" test "x" == '"$( c4.s.firstmatch "x" "o" "x" )"'
|
||||||
c4.t.b "s" 0 "firstmatch" "[!x o x] == o" test "o" == '"$( c4.s.firstmatch "!" "x" "" "x" "o" )"'
|
c4.t.b "s" 0 "firstmatch" "[!x x o] == o" test "o" == '"$( c4.s.firstmatch "!" "x" "" "x" "o" )"'
|
||||||
|
|
||||||
## give a friendly "did it work?" report
|
## give a friendly "did it work?" report
|
||||||
## TODO supress ANSI color-codes when STDOUT isn't a TTY
|
## TODO supress ANSI color-codes when STDOUT isn't a TTY
|
||||||
|
|
@ -325,10 +374,9 @@ function c4.updn {
|
||||||
fi
|
fi
|
||||||
echo -e "Load \e[1;${C4_UPDN_NC}m${what}\e[0m [\e[1;${color}m${up}\e[0m]$msg"
|
echo -e "Load \e[1;${C4_UPDN_NC}m${what}\e[0m [\e[1;${color}m${up}\e[0m]$msg"
|
||||||
}
|
}
|
||||||
#for n in $( seq 0 64 ) ; do (C4_UPDN_GC="$n";c4.updn "foo" "UP" "$n"); done
|
|
||||||
#echo_updown "foo" "up" "bar" #[[OK][[1;36mfoo[0m [[1;32mUP[0m] bar]]
|
|
||||||
|
|
||||||
### SYSUTIL
|
### SYSUTIL
|
||||||
|
#( function foo { declare -p; }; foo)
|
||||||
|
|
||||||
## print hostname if current (or given) file is on a spoke
|
## print hostname if current (or given) file is on a spoke
|
||||||
function c4.s.host {
|
function c4.s.host {
|
||||||
|
|
@ -413,163 +461,6 @@ c4.t.b "s" 0 "gw_is_localhost_f" "== hostname -f" test "0" == '"$(c4.gw_is_local
|
||||||
c4.t.b "s" 0 "gw_is_localhost" "== hostname -s" test "0" == '"$(c4.gw_is_localhost `hostname -s`; echo "$?")"'
|
c4.t.b "s" 0 "gw_is_localhost" "== hostname -s" test "0" == '"$(c4.gw_is_localhost `hostname -s`; echo "$?")"'
|
||||||
c4.t.b "s" 0 "name" "!= moo" test "1" == '"$(c4.gw_is_localhost "moo"; echo "$?")"'
|
c4.t.b "s" 0 "name" "!= moo" test "1" == '"$(c4.gw_is_localhost "moo"; echo "$?")"'
|
||||||
|
|
||||||
## check validity/availability of a node
|
|
||||||
_c4_is_gn=
|
|
||||||
function c4.i.is_gn {
|
|
||||||
seq "$(<.min)" "$(<.max)" | grep -v "$( perl -le 'printf q{\(%s\)}, join q{\|}, map {chomp;$_} <>' <.skip )" | grep "$(hostname -s | tr -d '[[:alpha:]]')" >/dev/null 2>&1 && echo OK
|
|
||||||
}
|
|
||||||
|
|
||||||
## Create a shell script by reading STDIN
|
|
||||||
_c4_mksh_infh=/dev/stdin # read from STDIN by default
|
|
||||||
_c4_mksh_otfh=/dev/stdout # write to STDOUT by default
|
|
||||||
_c4_mksh_bash=/usr/bin/bash # script for bash by default
|
|
||||||
function c4.mksh {
|
|
||||||
local C4_MKSH_INFH="$(c4.s.first "$C4_MKSH_INFH" "$_c4_mksh_infh" /dev/stdin)"
|
|
||||||
local C4_MKSH_OTFH="$(c4.s.first "$1" "$C4_MKSH_OTFH" "$_c4_mksh_otfh" /dev/stdout)"
|
|
||||||
local C4_MKSH_BASH="$(c4.s.first "$2" "$C4_MKSH_BASH" "$_c4_mksh_bash" /usr/bin/bash)"
|
|
||||||
|
|
||||||
printf '#!%s'"\n" "$C4_MKSH_BASH" >$C4_MKSH_OTFH
|
|
||||||
|
|
||||||
while IFS= read -r line; do
|
|
||||||
echo "$line" >> $C4_MKSH_OTFH
|
|
||||||
done <$C4_MKSH_INFH
|
|
||||||
|
|
||||||
# set the executable bit when making a regular file
|
|
||||||
test -f $C4_MKSH_OTFH && chmod a+x $C4_MKSH_OTFH
|
|
||||||
}
|
|
||||||
|
|
||||||
# run command on rhost via ssh when not on rhost
|
|
||||||
_c4_ssh_debug="$(c4.s.first "$_C4_SSH_DEBUG" "$C4_DEBUG")"
|
|
||||||
_C4_SSH="${_C4_SSH:-ssh}"
|
|
||||||
function c4.ssh {
|
|
||||||
local host="$1"; shift;
|
|
||||||
if c4.gw_is_localhost "$host" ; then # run locally
|
|
||||||
if test -z "$_c4_ssh_debug" ; then
|
|
||||||
$@
|
|
||||||
else
|
|
||||||
echo "$@"
|
|
||||||
fi
|
|
||||||
else # use ssh
|
|
||||||
local sshcmd="$( printf '%s %s' \
|
|
||||||
"$(c4.s.first $C4_SSH $_C4_SSH "ssh")" \
|
|
||||||
"$(c4.fqn "$host" )" \
|
|
||||||
)";
|
|
||||||
if test -z "$_c4_ssh_debug" ; then
|
|
||||||
$sshcmd $@
|
|
||||||
else
|
|
||||||
echo "$sshcmd $@"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
#local rhost="$( c4.gw_is_localhost "$1" && echo $1 )"
|
|
||||||
}
|
|
||||||
|
|
||||||
# run command on rhost via ssh when not on rhost
|
|
||||||
_c4_ssh_debug="$(c4.s.first "$_C4_SSH_DEBUG" "$C4_DEBUG")"
|
|
||||||
_C4_SSH="${_C4_SSH:-ssh}"
|
|
||||||
function c4.ssh2 {
|
|
||||||
if test -z "$1" ; then
|
|
||||||
echo "WF:C4.ssh empty or mssing hostname" 1>&2
|
|
||||||
return 1;
|
|
||||||
fi
|
|
||||||
|
|
||||||
_c4_ssh_hi=$1; shift;
|
|
||||||
_c4_ssh_ho=
|
|
||||||
_c4_ssh_hs=
|
|
||||||
_c4_ssh_hc=
|
|
||||||
|
|
||||||
# ensure we have both long and short name
|
|
||||||
if echo "$_c4_ssh_hi" | grep \. 1>/dev/null ; then
|
|
||||||
# TODO: could be smarter, given e.g. x.gw10.foo and is10 are gw10
|
|
||||||
_c4_ssh_hs="$( echo "$_c4_ssh_hi" | cut -d '.' -f 1 )"
|
|
||||||
_c4_ssh_ho="$_c4_ssh_hi";
|
|
||||||
else
|
|
||||||
_c4_hs="$_c4_ssh_hin";
|
|
||||||
_c4_ho="$( c4.fqn $_c4_hs )";
|
|
||||||
fi
|
|
||||||
|
|
||||||
if test "$C4_GW" != "$_c4_ssh_hs" ; then
|
|
||||||
_c4_ssh_hc="$(printf '%s %s ' "$_C4_SSH" "$_c4_ssh_ho")";
|
|
||||||
fi
|
|
||||||
|
|
||||||
if test -z "$_c4_ssh_debug" ; then
|
|
||||||
$_c4_ssh_hc"$@"
|
|
||||||
else
|
|
||||||
#echo "$_c4_ssh_hc"'"'"$@"'"'
|
|
||||||
local pre=
|
|
||||||
local post=
|
|
||||||
if test -n "$_c4_ssh_hc" ; then
|
|
||||||
pre="'"
|
|
||||||
post="'"
|
|
||||||
fi
|
|
||||||
echo "$_c4_ssh_hc$pre$@$post"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
## run mkdir locally if the given spoke is up, otherwise use SSH
|
|
||||||
_c4_mkdir_debug="$(c4.s.first "$_C4_MKDIR_DEBUG" "$C4_DEBUG")"
|
|
||||||
function c4.mkdir {
|
|
||||||
_c4_mkdir_islocal="$(
|
|
||||||
c4.s.host "$(
|
|
||||||
c4.s.firstmatch ! - "$@"
|
|
||||||
)"
|
|
||||||
)"
|
|
||||||
if test -n "$_c4_mkdir_islocal" ; then
|
|
||||||
if test -z "$_c4_mkdir_debug" ; then
|
|
||||||
mkdir $@
|
|
||||||
else
|
|
||||||
echo mkdir $@
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
c4.ssh mkdir $@
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
##
|
|
||||||
_c4_rsync_debug="$(c4.s.first "$_C4_RSYNC_DEBUG" "$C4_DEBUG")"
|
|
||||||
function c4.rsync {
|
|
||||||
local m== "$( c4.s.firstmatch ":" "$@" )";
|
|
||||||
if test -n "$m" ; then
|
|
||||||
m="$(echo "$m" | cut -d ':' -f 1)"
|
|
||||||
else
|
|
||||||
m="$(c4.s.host "$( c4.s.firstmatch ! ^ - "$@" )")"
|
|
||||||
fi
|
|
||||||
if test -n "$m" && c4.gw_is_localhost "$m"; then
|
|
||||||
if test -z "$_c4_rsync_debug" ; then
|
|
||||||
echo TROUBLE mkdir $@
|
|
||||||
else
|
|
||||||
echo mkdir $@
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
c4.ssh mkdir $@
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
# run command on rhost via ssh when not on rhost
|
|
||||||
_c4_cmd_debug="$(c4.s.first "$_C4_CMD_DEBUG" "$C4_DEBUG")"
|
|
||||||
# function c4.cmd {
|
|
||||||
# _c4_mkdir_islocal="$(
|
|
||||||
# c4.s.host "$(
|
|
||||||
# c4.s.firstmatch ! - "$@"
|
|
||||||
# )"
|
|
||||||
# )"
|
|
||||||
# if test -n "$_c4_mkdir_islocal" ; then
|
|
||||||
# if test -z "$_c4_rsync_debug" ; then
|
|
||||||
# $_c4__cmdpre $@
|
|
||||||
# else
|
|
||||||
# echo $_c4__cmdpre $@
|
|
||||||
# fi
|
|
||||||
#}
|
|
||||||
|
|
||||||
# run rsync on rhost via ssh when not on rhost
|
|
||||||
# function c4.rsync {
|
|
||||||
# if test -z "$_c4_rsync_debug" ; then
|
|
||||||
# $_c4_rsync_ssh $@
|
|
||||||
# else
|
|
||||||
# echo $_c4_rsync_ssh $@
|
|
||||||
# fi
|
|
||||||
# }
|
|
||||||
|
|
||||||
### IDENTITY
|
### IDENTITY
|
||||||
### - bootstrapping
|
### - bootstrapping
|
||||||
|
|
@ -594,22 +485,57 @@ function c4.i.gn_max () {
|
||||||
printf '%d' $C4_I_GN_MAX
|
printf '%d' $C4_I_GN_MAX
|
||||||
}
|
}
|
||||||
|
|
||||||
|
C4_I_GN_SKIP=
|
||||||
function c4.i.gn_skip {
|
function c4.i.gn_skip {
|
||||||
local gn=$1;
|
if test -n "$1" -o -z "$C4_I_GN_SKIP"; then
|
||||||
|
C4_I_GN_SKIP="$(c4.i.vals gn skip)";
|
||||||
#if test -z "$gn" -o ! "$gn" -gt "0"
|
fi
|
||||||
|
echo $C4_I_GN_SKIP
|
||||||
}
|
}
|
||||||
|
|
||||||
## return first identifier from source
|
C4_I_GN_SKIPPED=()
|
||||||
## where SOURCE is a readable file
|
function c4.i.gn_skipped {
|
||||||
function c4.i.val {
|
local gn=$1;
|
||||||
|
if test -z "$C4_I_GN_SKIPPED"; then
|
||||||
|
C4_I_GN_SKIPPED[$gn]=1
|
||||||
|
if test -n "$gn" \
|
||||||
|
-a 0 -lt "$gn" \
|
||||||
|
-a $(c4.i.gn_min) -le "$gn" \
|
||||||
|
-a $(c4.i.gn_max) -ge "$gn" \
|
||||||
|
>/dev/null 2>&1; then
|
||||||
|
C4_I_GN_SKIPPED[$gn]=0
|
||||||
|
local n;
|
||||||
|
for n in $(c4.i.gn_skip) ; do
|
||||||
|
if test "$gn" == "$n" ; then
|
||||||
|
C4_I_GN_SKIPPED[$gn]=1;
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
test 0 -eq "${C4_I_GN_SKIPPED[$gn]}"
|
||||||
|
}
|
||||||
|
|
||||||
|
## check validity/availability of a node
|
||||||
|
_c4_is_gn=
|
||||||
|
#function c4.i.is_gn {
|
||||||
|
#seq "$(<.min)" "$(<.max)" | grep -v "$( perl -le 'printf q{\(%s\)}, join q{\|}, map {chomp;$_} <>' <.skip )" | grep "$(hostname -s | tr -d '[[:alpha:]]')" >/dev/null 2>&1 && echo OK
|
||||||
|
#}
|
||||||
|
|
||||||
|
|
||||||
|
function c4.fa_src {
|
||||||
local src #="$(case $# in 1) $1 ;; *) $( c4.i.of $@ ) ;; esac) 1)"; shift;
|
local src #="$(case $# in 1) $1 ;; *) $( c4.i.of $@ ) ;; esac) 1)"; shift;
|
||||||
case $# in
|
case $# in
|
||||||
1) src=$1 ;;
|
1) src=$1 ;;
|
||||||
*) src=$( c4.i.of $@ ) ;;
|
*) src=$( c4.i.of $@ ) ;;
|
||||||
esac
|
esac
|
||||||
|
test -n "$src" && printf "%s" "$src"
|
||||||
|
}
|
||||||
|
|
||||||
|
## return first identifier from source
|
||||||
|
## where SOURCE is a readable file
|
||||||
|
function c4.i.val {
|
||||||
|
local src=$( c4.fa_src $@ )
|
||||||
if test ! -r "$src" ; then
|
if test ! -r "$src" ; then
|
||||||
# || test 0 == "$(file "$src" | grep text >2 2>&1; echo $?)"
|
# || test 0 == "$(file "$src" | grep text >2 2>&1; echo $?)"
|
||||||
echo "WARN" "C4R${C4_RUN}${C4_TR}_VAL: missing SRC" >&2 # LOG
|
echo "WARN" "C4R${C4_RUN}${C4_TR}_VAL: missing SRC" >&2 # LOG
|
||||||
|
|
@ -618,21 +544,71 @@ function c4.i.val {
|
||||||
head -1 $src
|
head -1 $src
|
||||||
}
|
}
|
||||||
|
|
||||||
|
## return source identifiers
|
||||||
|
## where SOURCE is a readable file
|
||||||
|
function c4.i.vals {
|
||||||
|
local src=$( c4.fa_src $@ )
|
||||||
|
if test ! -r "$src" ; then
|
||||||
|
echo "WARN" "C4R${C4_RUN}${C4_TR}_VAL: missing SRC" >&2 # LOG
|
||||||
|
return 1;
|
||||||
|
fi
|
||||||
|
cat $src
|
||||||
|
}
|
||||||
|
|
||||||
## call COMMAND for each identifier from SOURCE
|
## call COMMAND for each identifier from SOURCE
|
||||||
## where SOURCE is a readable file
|
## where SOURCE is a readable file
|
||||||
function c4.i.for {
|
function c4.i.for {
|
||||||
local src="$1"; shift;
|
local src=$( c4.fa_src $1 )
|
||||||
if test ! -r "$src" ; then
|
if test ! -r "$src" ; then
|
||||||
# || test 0 == "$(file "$src" | grep text >2 2>&1; echo $?)"
|
|
||||||
echo "WARN" "C4R${C4_RUN}${C4_TR}_FOR: missing SRC" >&2 # LOG
|
echo "WARN" "C4R${C4_RUN}${C4_TR}_FOR: missing SRC" >&2 # LOG
|
||||||
return 1;
|
return 1;
|
||||||
fi
|
fi
|
||||||
local line=;
|
|
||||||
while read line ; do
|
local line=; while read line ; do
|
||||||
$@ "'""$line""'"
|
$@ "'""$line""'"
|
||||||
done <$src
|
done <$src
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function c4.i.autosave {
|
||||||
|
test -z "$C4_I_INHIBIT_AUTOSAVE" \
|
||||||
|
|| return;
|
||||||
|
|
||||||
|
local src=$( c4.fa_src $1 ); shift
|
||||||
|
if test ! -r "$src" ; then
|
||||||
|
echo "WARN" "C4R${C4_RUN}${C4_TR}_AUTOSAVE: missing SRC" >&2 # LOG
|
||||||
|
return 1;
|
||||||
|
fi
|
||||||
|
|
||||||
|
cp $src $src~
|
||||||
|
}
|
||||||
|
|
||||||
|
function c4.i.clear {
|
||||||
|
local src=$( c4.fa_src $1 ); shift
|
||||||
|
if test ! -r "$src" ; then
|
||||||
|
echo "WARN" "C4R${C4_RUN}${C4_TR}_CLEAR: missing SRC" >&2 # LOG
|
||||||
|
return 1;
|
||||||
|
fi
|
||||||
|
c4.i.autosave $src
|
||||||
|
printf ''>$src
|
||||||
|
}
|
||||||
|
|
||||||
|
function c4.i.set {
|
||||||
|
local src=$( c4.fa_src $1 ); shift
|
||||||
|
if test ! -r "$src" ; then
|
||||||
|
echo "WARN" "C4R${C4_RUN}${C4_TR}_SET: missing SRC" >&2 # LOG
|
||||||
|
return 1;
|
||||||
|
fi
|
||||||
|
|
||||||
|
c4.i.clear $src # clear handles autosave (when not inhibitied)
|
||||||
|
|
||||||
|
local v;
|
||||||
|
for v in "$@" ; do
|
||||||
|
printf '%s'"\n" "$v" >>$src
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## return identity source of [[ <context1> [...]] query
|
## return identity source of [[ <context1> [...]] query
|
||||||
## where QUERY (and CONTEXT1, etc, if provided) are words
|
## where QUERY (and CONTEXT1, etc, if provided) are words
|
||||||
function c4.i.of {
|
function c4.i.of {
|
||||||
|
|
@ -705,9 +681,117 @@ function c4.s.sshfs {
|
||||||
echo "WARN" "C4R${C4_RUN}S_SSHFS: missing or non-directory TO \"$2\" (FROM \"$1\")" >&2 # LOG
|
echo "WARN" "C4R${C4_RUN}S_SSHFS: missing or non-directory TO \"$2\" (FROM \"$1\")" >&2 # LOG
|
||||||
return 1;
|
return 1;
|
||||||
fi
|
fi
|
||||||
: $C4_S_SSHFS_CMD $C4_S_SSHFS_OPT $@
|
$C4_S_SSHFS_CMD $C4_S_SSHFS_OPT $@
|
||||||
}
|
}
|
||||||
|
|
||||||
|
## run mkdir locally if the given spoke is up, otherwise use SSH
|
||||||
|
_c4_mkdir_debug="$(c4.s.first "$_C4_MKDIR_DEBUG" "$C4_DEBUG")"
|
||||||
|
function c4.mkdir {
|
||||||
|
_c4_mkdir_islocal="$(
|
||||||
|
c4.s.host "$(
|
||||||
|
c4.s.firstmatch ! - "$@"
|
||||||
|
)"
|
||||||
|
)"
|
||||||
|
if test -n "$_c4_mkdir_islocal" ; then
|
||||||
|
if test -z "$_c4_mkdir_debug" ; then
|
||||||
|
mkdir $@
|
||||||
|
else
|
||||||
|
echo mkdir $@
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
c4.ssh mkdir $@
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
## Create a shell script by reading STDIN
|
||||||
|
_c4_mksh_infh=/dev/stdin # read from STDIN by default
|
||||||
|
_c4_mksh_otfh=/dev/stdout # write to STDOUT by default
|
||||||
|
_c4_mksh_bash=/usr/bin/bash # script for bash by default
|
||||||
|
function c4.mksh {
|
||||||
|
local C4_MKSH_INFH="$(c4.s.first "$C4_MKSH_INFH" "$_c4_mksh_infh" /dev/stdin)"
|
||||||
|
local C4_MKSH_OTFH="$(c4.s.first "$1" "$C4_MKSH_OTFH" "$_c4_mksh_otfh" /dev/stdout)"
|
||||||
|
local C4_MKSH_BASH="$(c4.s.first "$2" "$C4_MKSH_BASH" "$_c4_mksh_bash" /usr/bin/bash)"
|
||||||
|
|
||||||
|
printf '#!%s'"\n" "$C4_MKSH_BASH" >$C4_MKSH_OTFH
|
||||||
|
|
||||||
|
while IFS= read -r line; do
|
||||||
|
echo "$line" >> $C4_MKSH_OTFH
|
||||||
|
done <$C4_MKSH_INFH
|
||||||
|
|
||||||
|
# set the executable bit when making a regular file
|
||||||
|
test -f $C4_MKSH_OTFH && chmod a+x $C4_MKSH_OTFH
|
||||||
|
}
|
||||||
|
|
||||||
|
# run command on rhost via ssh when not on rhost
|
||||||
|
_c4_ssh_debug="$(c4.s.first "$_C4_SSH_DEBUG" "$C4_DEBUG")"
|
||||||
|
_C4_SSH="${_C4_SSH:-ssh}"
|
||||||
|
function c4.ssh {
|
||||||
|
local host="$1"; shift;
|
||||||
|
if c4.gw_is_localhost "$host" ; then # run locally
|
||||||
|
if test -z "$_c4_ssh_debug" ; then
|
||||||
|
$@
|
||||||
|
else
|
||||||
|
echo "$@"
|
||||||
|
fi
|
||||||
|
else # use ssh
|
||||||
|
local sshcmd="$( printf '%s %s' \
|
||||||
|
"$(c4.s.first $C4_SSH $_C4_SSH "ssh")" \
|
||||||
|
"$(c4.fqn "$host" )" \
|
||||||
|
)";
|
||||||
|
if test -z "$_c4_ssh_debug" ; then
|
||||||
|
$sshcmd $@
|
||||||
|
else
|
||||||
|
echo "$sshcmd $@"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
##
|
||||||
|
_c4_rsync_debug="$(c4.s.first "$_C4_RSYNC_DEBUG" "$C4_DEBUG")"
|
||||||
|
function c4.rsync {
|
||||||
|
local m== "$( c4.s.firstmatch ":" "$@" )";
|
||||||
|
if test -n "$m" ; then
|
||||||
|
m="$(echo "$m" | cut -d ':' -f 1)"
|
||||||
|
else
|
||||||
|
m="$(c4.s.host "$( c4.s.firstmatch ! ^ - "$@" )")"
|
||||||
|
fi
|
||||||
|
if test -n "$m" && c4.gw_is_localhost "$m"; then
|
||||||
|
if test -z "$_c4_rsync_debug" ; then
|
||||||
|
echo TROUBLE mkdir $@
|
||||||
|
else
|
||||||
|
echo mkdir $@
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
c4.ssh mkdir $@
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# run command on rhost via ssh when not on rhost
|
||||||
|
_c4_cmd_debug="$(c4.s.first "$_C4_CMD_DEBUG" "$C4_DEBUG")"
|
||||||
|
# function c4.cmd {
|
||||||
|
# _c4_mkdir_islocal="$(
|
||||||
|
# c4.s.host "$(
|
||||||
|
# c4.s.firstmatch ! - "$@"
|
||||||
|
# )"
|
||||||
|
# )"
|
||||||
|
# if test -n "$_c4_mkdir_islocal" ; then
|
||||||
|
# if test -z "$_c4_rsync_debug" ; then
|
||||||
|
# $_c4__cmdpre $@
|
||||||
|
# else
|
||||||
|
# echo $_c4__cmdpre $@
|
||||||
|
# fi
|
||||||
|
#}
|
||||||
|
|
||||||
|
# run rsync on rhost via ssh when not on rhost
|
||||||
|
# function c4.rsync {
|
||||||
|
# if test -z "$_c4_rsync_debug" ; then
|
||||||
|
# $_c4_rsync_ssh $@
|
||||||
|
# else
|
||||||
|
# echo $_c4_rsync_ssh $@
|
||||||
|
# fi
|
||||||
|
# }
|
||||||
|
|
||||||
####
|
####
|
||||||
#### END
|
#### END
|
||||||
####
|
####
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue