diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/rpc.bash | 114 | ||||
-rw-r--r-- | src/rpc.main.bash | 5 |
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 | ||
17 | read_len() | ||
18 | { | ||
19 | REPLY= | ||
20 | [ "$1" -gt 0 ] && read -r -N"$1" && [ "$REPLY" ] | ||
21 | } | ||
22 | |||
23 | read_remote_command() | ||
24 | { | ||
25 | read_len "$1" | ||
26 | shift | ||
27 | remote_command=(bash -c "${REPLY@Q}" bash "${@@Q}") | ||
28 | } | ||
29 | |||
30 | remote_run_shell_script_stdin() | ||
31 | { | ||
32 | read_remote_command "$@" | ||
33 | ssh -- "${REMOTE_DEST}" "${remote_command[@]}" | ||
34 | } | ||
35 | |||
36 | remote_run_shell_script_tty() | ||
37 | { | ||
38 | read_remote_command "$@" | ||
39 | ssh -t -- "${REMOTE_DEST}" "${remote_command[@]}" </dev/tty | ||
40 | } | ||
41 | |||
42 | remote_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 | |||
57 | immediate_dependencies1() | 17 | immediate_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 | ||
74 | recursive_dependencies() | 32 | recursive_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 | ||
56 | bash_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. | ||
72 | bash_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 | |||
80 | remote_run_function_simple() | ||
81 | { | ||
82 | script_source=$(declare -f "$1" && printf '"$@";\n') | ||
83 | bash_rpc_remote_run_script "$script_source" "$@" | ||
84 | } | 84 | } |
85 | 85 | ||
86 | remote_run_function() | 86 | remote_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 | |||
11 | our_main() | 11 | our_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 | ||
29 | find_local_only_functions() | 29 | find_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 | ||
36 | all_commands() | 37 | all_commands() |