diff options
author | Andrew Cady <d@jerkface.net> | 2023-08-27 11:15:23 -0400 |
---|---|---|
committer | Andrew Cady <d@jerkface.net> | 2023-08-27 11:15:23 -0400 |
commit | b01d26fcc596f46f20207f17636331f7916bb0ac (patch) | |
tree | c5b26e15de8988b0a1484a82c08657f322467349 /src | |
parent | 0ffdac14345e4c7de708e75e98a9a9e3aaa9fefb (diff) |
bashrpc cleanups
Diffstat (limited to 'src')
-rw-r--r-- | src/dependencies.bash | 43 | ||||
-rw-r--r-- | src/rpc.bash | 136 | ||||
-rw-r--r-- | src/rpc.main.bash | 4 |
3 files changed, 109 insertions, 74 deletions
diff --git a/src/dependencies.bash b/src/dependencies.bash new file mode 100644 index 0000000..b6eee95 --- /dev/null +++ b/src/dependencies.bash | |||
@@ -0,0 +1,43 @@ | |||
1 | #!/bin/false | ||
2 | |||
3 | intersection() | ||
4 | { | ||
5 | comm -12 "$@" | ||
6 | } | ||
7 | |||
8 | difference() | ||
9 | { | ||
10 | comm -23 "$@" | ||
11 | } | ||
12 | |||
13 | extract_words() | ||
14 | { | ||
15 | grep -o -E '\b\w+\b' | sort -u | ||
16 | } | ||
17 | |||
18 | immediate_dependencies1() | ||
19 | { | ||
20 | intersection \ | ||
21 | <(compgen -A function | sort -u) \ | ||
22 | <(declare -f "$1" | extract_words) | ||
23 | } | ||
24 | |||
25 | immediate_dependencies() | ||
26 | { | ||
27 | (for f | ||
28 | do | ||
29 | immediate_dependencies1 "$f" | ||
30 | done) | sort -u | ||
31 | } | ||
32 | |||
33 | recursive_dependencies() | ||
34 | { | ||
35 | local seen=() | ||
36 | while [ $# -gt 0 ] | ||
37 | do | ||
38 | seen+=("$@") | ||
39 | set -- $(difference <(immediate_dependencies "$@") \ | ||
40 | <(printf '%s\n' "${seen[@]}" | sort -u)) | ||
41 | done | ||
42 | printf '%s\n' "${seen[@]}" | ||
43 | } | ||
diff --git a/src/rpc.bash b/src/rpc.bash index e7216a5..d13942b 100644 --- a/src/rpc.bash +++ b/src/rpc.bash | |||
@@ -1,52 +1,6 @@ | |||
1 | #!/bin/false | ||
1 | 2 | ||
2 | intersection() | 3 | source dependencies.bash |
3 | { | ||
4 | comm -12 "$@" | ||
5 | } | ||
6 | |||
7 | difference() | ||
8 | { | ||
9 | comm -23 "$@" | ||
10 | } | ||
11 | |||
12 | extract_words() | ||
13 | { | ||
14 | grep -o -E '\b\w+\b' | sort -u | ||
15 | } | ||
16 | |||
17 | immediate_dependencies1() | ||
18 | { | ||
19 | intersection \ | ||
20 | <(compgen -A function | sort -u) \ | ||
21 | <(declare -f "$1" | extract_words) | ||
22 | } | ||
23 | |||
24 | immediate_dependencies() | ||
25 | { | ||
26 | for f | ||
27 | do | ||
28 | immediate_dependencies1 "$f" | ||
29 | done | sort -u | ||
30 | } | ||
31 | |||
32 | recursive_dependencies() | ||
33 | { | ||
34 | seen=() | ||
35 | while [ $# -gt 0 ] | ||
36 | do | ||
37 | seen+=("$@") | ||
38 | set -- $(difference <(immediate_dependencies "$@") \ | ||
39 | <(printf '%s\n' "${seen[@]}" | sort -u)) | ||
40 | done | ||
41 | printf '%s\n' "${seen[@]}" | ||
42 | } | ||
43 | |||
44 | |||
45 | |||
46 | |||
47 | |||
48 | |||
49 | |||
50 | 4 | ||
51 | # Input: $BASH_RPC_REMOTE_DEST - hostname passed to ssh (uses ssh host aliases) | 5 | # 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 '--') | 6 | # Input: $BASH_RPC_SSH_OPTIONS - option arguments passed to ssh (they precede '--') |
@@ -55,46 +9,71 @@ recursive_dependencies() | |||
55 | # Input: $2, $3, ... - command line arguments passed to the remote bash as $1, $2, ... | 9 | # Input: $2, $3, ... - command line arguments passed to the remote bash as $1, $2, ... |
56 | # Input: stdin, stdout, stderr: passed to the remote bash over ssh | 10 | # Input: stdin, stdout, stderr: passed to the remote bash over ssh |
57 | # Input: "$SHELL" - remote shell to launch (better be bash) | 11 | # Input: "$SHELL" - remote shell to launch (better be bash) |
58 | bash_rpc_remote_run_script() | 12 | __bashrpc__remote_run_script() |
59 | { | 13 | { |
60 | local script="$1" | 14 | local script="$1" |
61 | shift | 15 | shift |
16 | BASH_RPC_SHELL_OPTIONS=(--norc --noprofile) | ||
17 | set -x | ||
18 | # printf 'DEBUG:<%s>\n' "${BASH_RPC_SSH_OPTIONS[@]}" >&2 | ||
62 | exec ssh \ | 19 | exec ssh \ |
63 | "${BASH_RPC_SSH_OPTIONS[@]}" -- \ | 20 | "${BASH_RPC_SSH_OPTIONS[@]}" -- \ |
64 | "${BASH_RPC_REMOTE_DEST:-localhost}" \ | 21 | "${BASH_RPC_REMOTE_DEST:-localhost}" \ |
65 | "$SHELL" -c "${script@Q}" "$0" "${@@Q}" | 22 | "$SHELL" "${BASH_RPC_SHELL_OPTIONS[@]}" \ |
23 | -c "${script@Q}" \ | ||
24 | "$0" "${@@Q}" | ||
66 | } | 25 | } |
67 | 26 | ||
68 | bash_rpc_with_ssh_option() | 27 | with_ssh_options() { __bashrpc__with_ssh_options "$@"; } |
28 | __bashrpc__with_ssh_options() | ||
69 | { | 29 | { |
70 | local BASH_RPC_SSH_OPTIONS | 30 | local -a BASH_RPC_SSH_OPTIONS |
31 | while [ "$1" != '--' ] | ||
32 | do | ||
33 | if [ $# -gt 0 ] | ||
34 | then | ||
35 | BASH_RPC_SSH_OPTIONS+=("$1") | ||
36 | shift | ||
37 | continue | ||
38 | fi | ||
39 | >&2 printf '%s: Error: %s\n' "$0" \ | ||
40 | 'with_ssh_options(): expected argument "--" not found' | ||
41 | exit 1 | ||
42 | done | ||
43 | shift | ||
44 | "$@" | ||
45 | } | ||
46 | |||
47 | with_ssh_option() { __bashrpc__with_ssh_option "$@"; } | ||
48 | __bashrpc__with_ssh_option() | ||
49 | { | ||
50 | local -a BASH_RPC_SSH_OPTIONS=("${BASH_RPC_SSH_OPTIONS[@]}") | ||
71 | BASH_RPC_SSH_OPTIONS+=("$1") | 51 | BASH_RPC_SSH_OPTIONS+=("$1") |
72 | shift | 52 | shift |
73 | "$@" | 53 | "$@" |
74 | } | 54 | } |
75 | 55 | ||
76 | # Preserves the rest of stdin for the command. | 56 | # Preserves the rest of stdin for the command. |
77 | bash_rpc_eval_stdin() | 57 | __bashrpc__eval_stdin() |
78 | { | 58 | { |
79 | [ "$1" -gt 0 ] || return | 59 | [ "$1" ] && read -N"$1" -r || return |
80 | read -N"$1" -r || return | ||
81 | 60 | ||
82 | # Prepare "$@" for script execution context. | 61 | # Prepare "$@" for script execution context. |
83 | shift | 62 | shift |
84 | 63 | ||
85 | # Even unset REPLY to leave pristine environment. | 64 | # Even unset REPLY to leave pristine environment. |
86 | eval "unset REPLY; $(cat <<< "$REPLY")" | 65 | eval "unset REPLY; $REPLY" |
87 | } | 66 | } |
88 | 67 | ||
89 | bash_rpc_run_function_simple() | 68 | __bashrpc__run_function_simple() |
90 | { | 69 | { |
91 | script_source=$(declare -f "$1" && printf '"$@";\n') | 70 | script_source=$(declare -f "$1" && printf '"$@";\n') |
92 | bash_rpc_remote_run_script \ | 71 | __bashrpc__remote_run_script \ |
93 | "$script_source" \ | 72 | "$script_source" \ |
94 | "$@" | 73 | "$@" |
95 | } | 74 | } |
96 | 75 | ||
97 | remote_run_stage1_notty() | 76 | __bashrpc__remote_run_stage1_notty() |
98 | { | 77 | { |
99 | stage2_source=$1 | 78 | stage2_source=$1 |
100 | shift | 79 | shift |
@@ -102,38 +81,47 @@ remote_run_stage1_notty() | |||
102 | printf '%s' "$stage2_source" | 81 | printf '%s' "$stage2_source" |
103 | cat | 82 | cat |
104 | } | | 83 | } | |
105 | bash_rpc_run_function_simple \ | 84 | __bashrpc__run_function_simple \ |
106 | bash_rpc_eval_stdin \ | 85 | __bashrpc__eval_stdin \ |
107 | "${#stage2_source}" \ | 86 | "${#stage2_source}" \ |
108 | "$@" | 87 | "$@" |
109 | } | 88 | } |
110 | 89 | ||
111 | read_stdin() | 90 | __bashrpc__read_stdin() |
112 | { | 91 | { |
113 | REPLY= | 92 | REPLY= |
114 | read -r -N2147483647 || [ "$REPLY" ] | 93 | read -r -N2147483647 || [ "$REPLY" ] |
115 | } | 94 | } |
116 | 95 | ||
117 | tty_stage1() | 96 | __bashrpc__tty_stage1() |
118 | { | 97 | { |
119 | local SET_TERM="$1" | 98 | local SET_TERM="$1" |
120 | read_stdin <<END | 99 | local prelude="shift;${BASH_RPC_TRACE_REMOTE:+ set -x;}" |
121 | set -- "\$TERM" "\$@" | 100 | __bashrpc__read_stdin <<END |
122 | TERM=${SET_TERM@Q} | 101 | # We saved stage2 in TERM. |
123 | source <(echo shift; printf '%s' "\$1") | 102 | # Store it in parameter 1: |
103 | set -- "\$TERM" "\$@" | ||
104 | # Restore original TERM: | ||
105 | TERM=${SET_TERM@Q} | ||
106 | # Run stage2: | ||
107 | source <( | ||
108 | printf '%s\n' "$prelude" | ||
109 | printf '%s' "\$1" | ||
110 | ) | ||
124 | END | 111 | END |
125 | printf '%s' "$REPLY" | 112 | printf '%s' "$REPLY" |
126 | } | 113 | } |
127 | 114 | ||
128 | remote_run_stage1_tty() | 115 | __bashrpc__remote_run_stage1_tty() |
129 | { | 116 | { |
130 | stage2_source=$1 | 117 | stage2_source=$1 |
131 | stage1_source=$(tty_stage1 "$TERM") | 118 | stage1_source=$(__bashrpc__tty_stage1 "$TERM") |
132 | shift | 119 | shift |
133 | ( | 120 | ( |
121 | # printf 'DEBUG2:<%s>\n' "${BASH_RPC_SSH_OPTIONS[@]}" >&2 | ||
134 | TERM="$stage2_source" \ | 122 | TERM="$stage2_source" \ |
135 | bash_rpc_with_ssh_option -t \ | 123 | __bashrpc__with_ssh_option -t \ |
136 | bash_rpc_remote_run_script \ | 124 | __bashrpc__remote_run_script \ |
137 | "$stage1_source" "$@" | 125 | "$stage1_source" "$@" |
138 | ) | 126 | ) |
139 | } | 127 | } |
@@ -141,6 +129,7 @@ remote_run_stage1_tty() | |||
141 | remote_run_function() | 129 | remote_run_function() |
142 | { | 130 | { |
143 | main=$1 | 131 | main=$1 |
132 | # funcs=$(compgen -A function) | ||
144 | funcs=$(recursive_dependencies "$main") | 133 | funcs=$(recursive_dependencies "$main") |
145 | stage2_source=$( | 134 | stage2_source=$( |
146 | declare -f $funcs | 135 | declare -f $funcs |
@@ -148,8 +137,9 @@ remote_run_function() | |||
148 | ) | 137 | ) |
149 | if [ -t 0 ] | 138 | if [ -t 0 ] |
150 | then | 139 | then |
151 | remote_run_stage1_tty "$stage2_source" "$@" | 140 | __bashrpc__remote_run_stage1_tty "$stage2_source" "$@" |
152 | else | 141 | else |
153 | remote_run_stage1_notty "$stage2_source" "$@" | 142 | __bashrpc__remote_run_stage1_notty "$stage2_source" "$@" |
154 | fi | 143 | fi |
155 | } | 144 | } |
145 | |||
diff --git a/src/rpc.main.bash b/src/rpc.main.bash index 9fba425..c34296e 100644 --- a/src/rpc.main.bash +++ b/src/rpc.main.bash | |||
@@ -17,6 +17,8 @@ our_main() | |||
17 | 17 | ||
18 | main1() | 18 | main1() |
19 | { | 19 | { |
20 | # local -a BASH_RPC_SSH_OPTIONS=('-4' '-6' '-4') | ||
21 | with_ssh_options -4 -6 -4 -- \ | ||
20 | remote_run_function fudge "$@" | 22 | remote_run_function fudge "$@" |
21 | } | 23 | } |
22 | 24 | ||
@@ -49,7 +51,7 @@ gudge() | |||
49 | 51 | ||
50 | fudge() | 52 | fudge() |
51 | { | 53 | { |
52 | read -p 'Name? ' && gudge "$@" | 54 | read -p "[$(hostname)] Name? " && gudge "$@" |
53 | exit | 55 | exit |
54 | } | 56 | } |
55 | 57 | ||