add login option

add shell option
add environment variable option
fix a couple bugs
add test function and test function launcher function
master
David Kebler 2024-02-22 13:43:48 -08:00
parent c756711123
commit 960790195c
1 changed files with 57 additions and 23 deletions

View File

@ -23,7 +23,7 @@ remote_script () {
local sshargs;local user;local supass;local cfn; local rfn; local args; local sshargs;local user;local supass;local cfn; local rfn; local args;
local script; local host; local dr; local supass; local env_vars; local script; local host; local dr; local supass; local env_vars;
local login; local slogin local login; local slogin; local shell=bash
local hostname; local bscript; local ruser; local usesudo; local save local hostname; local bscript; local ruser; local usesudo; local save
help() { help() {
@ -31,14 +31,18 @@ remote_script () {
cat <<EOF cat <<EOF
usage: remote_script <remote_script options> host script <script args> -- <ssh script options> usage: remote_script <remote_script options> host script <script args> -- <ssh script options>
host and script are required, script can be either path to a file containing a script to a UCI module host and script are required, script can be either path to a file containing a script to a UCI module
-f, <func> run a function in the passed script, otherwise script is assumed to be bash executed.
-x, <func> create script of just a function from some script file or module
| will automatically set -f to run that function.
-b <shell> use another shell processor other than default bash
-d, dry run. don't run the rscript just output the command that will be run
-u, <ruser> remote user to run script as. default is ssh host user or root if using sudo.
| if -u is other than ssh login user then -s or -p must be set
-s, execute remote script using sudo -s, execute remote script using sudo
-f, run a function in the passed script, otherwise script is assumed to be bash executed. -p, <suppass> sudo password. If set teh remote command will be run as root or the user of -u <user>
-d, dry run. don't run the rscript just output the command that will be run | if command has 'ssh script option' of '-- -p <upasswd>' and -s is set this will set -p <upasswd> automatically
-u, remote user to run script as. default is ssh host user or root if using sudo
-p, password for ssh login, will also be used for sudo assuming remote user is in sudo group
-x, create script from available function instead of module or file
-l, use login shell on remote -l, use login shell on remote
-e, set some environment variables to run -e, <SOME_VAR="some value"> set some environment variables to run. Can be used more than once for multiple values
-h, this help text -h, this help text
EOF EOF
@ -65,13 +69,17 @@ EOF
local OPTION local OPTION
local OPTARG local OPTARG
local OPTIND local OPTIND
while getopts 'le:hdu:sf:p:x:' OPTION; do while getopts 'b:le:hdu:sf:p:x:' OPTION; do
# echo OPTION $OPTION ARG $OPTARG INDX $OPTIND # echo OPTION $OPTION ARG $OPTARG INDX $OPTIND
case "$OPTION" in case "$OPTION" in
s) s)
# using sudo, password will come from ssh user password or if you supply it with -p # using sudo, password will come from ssh user password or if you supply it with -p
usesudo=true usesudo=true
;; ;;
b)
# use another shell the than default bash
shell="$OPTARG"
;;
f) f)
# run a function within the script # run a function within the script
# any function arguments appear after script # any function arguments appear after script
@ -82,7 +90,8 @@ EOF
dr=true dr=true
;; ;;
e) e)
env_vars+=" $OPTARG"
env_vars+=" $(escape_spaces "$OPTARG")"
;; ;;
u) u)
# run remote command as another user # run remote command as another user
@ -90,14 +99,13 @@ EOF
# usesudo=true # usesudo=true
;; ;;
l) l)
login="bash -l" login="-l"
;; ;;
x) x)
rfn=$OPTARG rfn=$OPTARG
;; ;;
p) p)
# password of sudo account for running as root or other user
# will force running as root on remote if ruser is not specified
supass=$OPTARG supass=$OPTARG
;; ;;
h) h)
@ -129,8 +137,8 @@ EOF
[[ -f $1 ]] && source $1 [[ -f $1 ]] && source $1
fi fi
if ! declare -f $rfn >/dev/null; then echo fatal: remote-script, unable to source funtion $rfn, aborting; return 1; fi if ! declare -f $rfn >/dev/null; then echo fatal: remote-script, unable to source funtion $rfn, aborting; return 1; fi
shift
fi fi
shift
local file local file
script=$(mkrfilename temp_function) script=$(mkrfilename temp_function)
declare -f $rfn > $script declare -f $rfn > $script
@ -151,8 +159,8 @@ EOF
if [[ $usesudo ]] || [[ $supass ]]; then if [[ $usesudo ]] || [[ $supass ]]; then
[[ $usesudo ]] && supass=$(parse_option "${sshargs[*]}" -p) [[ $usesudo ]] && supass=$(parse_option "${sshargs[*]}" -p)
if [[ $supass ]]; then if [[ $supass ]]; then
[[ $login ]] && login="" && slogin="-i" [[ $login ]] && slogin="-i"
usesudo="echo '${supass}' | sudo $slogin -u ${ruser:-root} --stdin 2>/dev/null" usesudo="echo '${supass}' | sudo $slogin -u ${ruser:-root} --stdin 2>/dev/null"
echo remote script to be run as ${ruser:-root} using sudo echo remote script to be run as ${ruser:-root} using sudo
else else
echo sudo requested but no sudo password supplied, aborting echo sudo requested but no sudo password supplied, aborting
@ -160,15 +168,15 @@ EOF
fi fi
fi fi
debug remote script arguments $(remote_args "$@") debug remote script arguments $(escape_args "$@")
debug ssh arguments $(remote_args "${sshargs[@]}") debug ssh arguments $(escape_args "${sshargs[@]}")
rscript=${save:-$(mkrfilename REMOTE_SCRIPT)} rscript=${save:-$(mkrfilename REMOTE_SCRIPT)}
if sshcp -d $host $bscript $rscript -- "${sshargs[@]}"; then if sshcp -d $host $bscript $rscript -- "${sshargs[@]}"; then
# make remote script excuteable # make remote script excuteable
ssh "${sshargs[@]}" "$host" "chmod +x $rscript" ssh "${sshargs[@]}" "$host" "chmod +x $rscript"
# run the script # run the script
ssh "${sshargs[@]}" "$host" "$usesudo" $login "$env_vars" "$rscript" "$(remote_args "$@")" ssh "${sshargs[@]}" "$host" "$usesudo" "$env_vars" "$shell" $login "$rscript" "$(escape_args "$@")"
# now delete it, save script if passed an explicit name # now delete it, save script if passed an explicit name
if ! ssh "${sshargs[@]}" $host rm -f $rscript; then echo unable to delete temporary remote file at $host:$rscript; fi if ! ssh "${sshargs[@]}" $host rm -f $rscript; then echo unable to delete temporary remote file at $host:$rscript; fi
# ssh "${sshargs[@]}" "$host" "cat $rscript" # ssh "${sshargs[@]}" "$host" "cat $rscript"
@ -183,21 +191,47 @@ EOF
# END REMOTE SCRIPT # END REMOTE SCRIPT
# # if script was executed then call the function
(return 0 2>/dev/null) ||remote_script $@
# can be used with a file or HEREDOC # can be used with a file or HEREDOC
# todo test with < $file or with a pipe # todo test with < $file or with a pipe
remote_stdin () { remote_stdin () {
local file local file
# echo args $@ echo "remote send multiple commands for cli, type commands"
echo "then cntrl-d to end and send"
file=$( mkrfilename remote_script ) file=$( mkrfilename remote_script )
cat > $file cat > $file
remote_script $1 "$file" "$@" remote_script $1 "$file" "$@"
rm -f $file &> /dev/null rm -f $file &> /dev/null
} }
# # if script was executed then call the function
(return 0 2>/dev/null) ||remote_script $@
remote_test () {
local pass
echo "to run: remote_test host password"
[[ $2 ]] && pass="-- -p $2"
echo "------------ test one, no login shell, regular user ------------------"
echo "running: remote_script -f -x remote_test_script -e ENV_TEST="test env variable" $1 remote arg1 "arg 2" arg3 arg4 $pass"
remote_script -x remote_test_script -e ENV_TEST="test env variable" $1 remote arg1 "arg 2" arg3 arg4 $pass
echo "------------ test two, login shell, regular user ------------------"
remote_script -l -x remote_test_script -e ENV_TEST="test env variable" $1 remote arg1 "arg 2" arg3 arg4 $pass
echo "------------ test three, no login shell, root/sudo user ------------------"
remote_script -s -x remote_test_script -e ENV_TEST="test env variable" $1 remote arg1 "arg 2" arg3 arg4 $pass
echo "------------ test four, login shell, root/sudo user ------------------"
remote_script -s -l -x remote_test_script -e ENV_TEST="test env variable" $1 remote arg1 "arg 2" arg3 arg4 $pass
echo "-------------------- done tests ----------------"
}
remote_test_script () {
shopt -q login_shell && echo 'Login shell' || echo 'Not login shell'
env | grep SHELL_BASE
echo ENV_TEST: $ENV_TEST
echo running on machine: $(hostnamectl hostname)
echo as user:home $(whoami):$HOME
echo argument1 $1
echo argument2 $2
echo remaining arguments: "${@:3}"
}