summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAndrew Cady <d@jerkface.net>2023-08-27 11:15:23 -0400
committerAndrew Cady <d@jerkface.net>2023-08-27 11:15:23 -0400
commitb01d26fcc596f46f20207f17636331f7916bb0ac (patch)
treec5b26e15de8988b0a1484a82c08657f322467349 /src
parent0ffdac14345e4c7de708e75e98a9a9e3aaa9fefb (diff)
bashrpc cleanups
Diffstat (limited to 'src')
-rw-r--r--src/dependencies.bash43
-rw-r--r--src/rpc.bash136
-rw-r--r--src/rpc.main.bash4
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
3intersection()
4{
5 comm -12 "$@"
6}
7
8difference()
9{
10 comm -23 "$@"
11}
12
13extract_words()
14{
15 grep -o -E '\b\w+\b' | sort -u
16}
17
18immediate_dependencies1()
19{
20 intersection \
21 <(compgen -A function | sort -u) \
22 <(declare -f "$1" | extract_words)
23}
24
25immediate_dependencies()
26{
27 (for f
28 do
29 immediate_dependencies1 "$f"
30 done) | sort -u
31}
32
33recursive_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
2intersection() 3source dependencies.bash
3{
4 comm -12 "$@"
5}
6
7difference()
8{
9 comm -23 "$@"
10}
11
12extract_words()
13{
14 grep -o -E '\b\w+\b' | sort -u
15}
16
17immediate_dependencies1()
18{
19 intersection \
20 <(compgen -A function | sort -u) \
21 <(declare -f "$1" | extract_words)
22}
23
24immediate_dependencies()
25{
26 for f
27 do
28 immediate_dependencies1 "$f"
29 done | sort -u
30}
31
32recursive_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)
58bash_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
68bash_rpc_with_ssh_option() 27with_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
47with_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.
77bash_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
89bash_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
97remote_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
111read_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
117tty_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:
103set -- "\$TERM" "\$@"
104# Restore original TERM:
105TERM=${SET_TERM@Q}
106# Run stage2:
107source <(
108 printf '%s\n' "$prelude"
109 printf '%s' "\$1"
110)
124END 111END
125 printf '%s' "$REPLY" 112 printf '%s' "$REPLY"
126} 113}
127 114
128remote_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()
141remote_run_function() 129remote_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
18main1() 18main1()
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
50fudge() 52fudge()
51{ 53{
52 read -p 'Name? ' && gudge "$@" 54 read -p "[$(hostname)] Name? " && gudge "$@"
53 exit 55 exit
54} 56}
55 57