summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Cady <d@jerkface.net>2023-08-25 16:54:07 -0400
committerAndrew Cady <d@jerkface.net>2023-08-25 16:54:07 -0400
commit1ed2f3f601b8a720b8c9cfd285bfc56a43670f2c (patch)
tree99b18b68f3ea1417bdbf4c5f80c5446977e185f6
parent6312004af0bc5d488e6dd1d6ec7744743138c649 (diff)
WIP
-rw-r--r--src/rpc.bash114
-rw-r--r--src/rpc.main.bash5
2 files changed, 62 insertions, 57 deletions
diff --git a/src/rpc.bash b/src/rpc.bash
index 644df95..eb41538 100644
--- a/src/rpc.bash
+++ b/src/rpc.bash
@@ -14,50 +14,8 @@ extract_words()
14 grep -o -E '\b\w+\b' | sort -u 14 grep -o -E '\b\w+\b' | sort -u
15} 15}
16 16
17read_len()
18{
19 REPLY=
20 [ "$1" -gt 0 ] && read -r -N"$1" && [ "$REPLY" ]
21}
22
23read_remote_command()
24{
25 read_len "$1"
26 shift
27 remote_command=(bash -c "${REPLY@Q}" bash "${@@Q}")
28}
29
30remote_run_shell_script_stdin()
31{
32 read_remote_command "$@"
33 ssh -- "${REMOTE_DEST}" "${remote_command[@]}"
34}
35
36remote_run_shell_script_tty()
37{
38 read_remote_command "$@"
39 ssh -t -- "${REMOTE_DEST}" "${remote_command[@]}" </dev/tty
40}
41
42remote_run_shell_script_arg1()
43{
44 script=$1
45 shift
46 set -- "${#script}" "$@"
47 if test -t 0 && test -t 1
48 then
49 printf '%s' "$script" |
50 remote_run_shell_script_tty "$@"
51 else
52 cat <(printf '%s' "$script") - |
53 remote_run_shell_script_stdin "$@"
54 fi
55}
56
57immediate_dependencies1() 17immediate_dependencies1()
58{ 18{
59 # Thanks Lri from stackoverflow.com/questions/4471364/
60 # how-do-i-list-the-functions-defined-in-my-shell/28278090
61 intersection \ 19 intersection \
62 <(compgen -A function | sort -u) \ 20 <(compgen -A function | sort -u) \
63 <(declare -f "$1" | extract_words) 21 <(declare -f "$1" | extract_words)
@@ -73,29 +31,75 @@ immediate_dependencies()
73 31
74recursive_dependencies() 32recursive_dependencies()
75{ 33{
76 resolved=() 34 seen=()
77 while [ $# -gt 0 ] 35 while [ $# -gt 0 ]
78 do 36 do
79 resolved+=("$@") 37 seen+=("$@")
80 set -- $(difference <(immediate_dependencies "$@") \ 38 set -- $(difference <(immediate_dependencies "$@") \
81 <(printf '%s\n' "${resolved[@]}" | sort -u)) 39 <(printf '%s\n' "${seen[@]}" | sort -u))
82 done 40 done
83 printf '%s\n' "${resolved[@]}" 41 printf '%s\n' "${seen[@]}"
42}
43
44
45
46
47
48
49
50
51# Input: $BASH_RPC_REMOTE_DEST - hostname passed to ssh (uses ssh host aliases)
52# Input: $BASH_RPC_SSH_OPTIONS - option arguments passed to ssh (they precede '--')
53# Input: $1 - bash shell script source code to run remotely
54# Input: $2, $3, ... - command line arguments passed to the remote bash shell
55# Input: stdin, stdout, stderr: passed to ssh
56bash_rpc_remote_run_script()
57{
58 (
59 local script="$1"
60 shift
61 set -- "$SHELL" -c "${script@Q}" "$0" "${@@Q}"
62 set -x
63 exec ssh \
64 "${BASH_RPC_SSH_OPTIONS[@]}" \
65 -- \
66 "${BASH_RPC_REMOTE_DEST:-localhost}" \
67 "$@"
68 )
69}
70
71# Preserves the rest of stdin for the command.
72bash_rpc_eval_stdin()
73{
74 [ "$1" -gt 0 ] || return
75 read -N"$1" -r || return
76 shift # prepare "$@" for script execution context
77 source <(printf '%s' "$REPLY" | tr -d '\015')
78}
79
80remote_run_function_simple()
81{
82 script_source=$(declare -f "$1" && printf '"$@";\n')
83 bash_rpc_remote_run_script "$script_source" "$@"
84} 84}
85 85
86remote_run_function() 86remote_run_function()
87{ 87{
88 main=$1 88 main=$1
89 shift
90 funcs=$(recursive_dependencies "$main") 89 funcs=$(recursive_dependencies "$main")
91 90 stage2_source=$(
92 script=
93 read -N2147483647 -r script < <(
94 declare -f $funcs 91 declare -f $funcs
95 printf '%s "$@";\n' "$main" 92 printf '"$@"\n' "$main"
96 ) || true 93 )
97 [ "$script" ] 94 BASH_RPC_SSH_OPTIONS=(-tt)
98 95 {
99 remote_run_shell_script_arg1 "$script" "$@" 96 printf '%s' "$stage2_source"
97 if [ -t 0 ]
98 then
99 socat stdio PTY
100 else
101 cat
102 fi
103 } | remote_run_function_simple bash_rpc_eval_stdin "${#stage2_source}" "$@"
100} 104}
101 105
diff --git a/src/rpc.main.bash b/src/rpc.main.bash
index b859509..9fba425 100644
--- a/src/rpc.main.bash
+++ b/src/rpc.main.bash
@@ -11,7 +11,7 @@ esac
11our_main() 11our_main()
12{ 12{
13 REMOTE_DEST=localhost 13 REMOTE_DEST=localhost
14 main2 "$@" 14# main2 "$@"
15 main1 "$@" 15 main1 "$@"
16} 16}
17 17
@@ -28,9 +28,10 @@ main2()
28 28
29find_local_only_functions() 29find_local_only_functions()
30{ 30{
31 remote_commands=($(remote_run_function all_commands | sort -u))
31 intersection <(extract_words < "$BASH_SOURCE") \ 32 intersection <(extract_words < "$BASH_SOURCE") \
32 <(difference <(all_commands) \ 33 <(difference <(all_commands) \
33 <(remote_run_function all_commands)) 34 <(printf '%s\n' "${remote_commands[@]}"))
34} 35}
35 36
36all_commands() 37all_commands()