make getpeername() return the original socket address which before it was intercepted
[hband-tools.git] / user-tools / partial
blobac4cac7f3456824389423b6282ed3894eb3a0b6b
1 #!/bin/bash
3 true <<EOF
4 =pod
6 =head1 NAME
8 partial - Show an earlier started long-running command's partial output
10 =head1 SYNOPSIS
12 partial [--restart|--forget|--wait|--pid] <B<COMMAND>> [<B<ARGUMENTS>>]
14 =head1 DESCRIPTION
16 On first invocation partial(1) starts B<COMMAND> in the background.
17 On subsequent invocations, it prints the command's output to stdout which is
18 generated so far, including the parts which are shown before too,
19 and keep it running in the background.
20 Hence the name 'partial', because it shows a command's partial output.
21 When the command finished, partial(1) prints the whole output
22 and exits with B<COMMAND>'s exit code.
24 =head1 OPTIONS
26 =over 4
28 =item -f, --forget
30 Terminate (SIGTERM) previous instance of the same command
31 and clean up status directory, even if it's running.
33 =item -r, --restart
35 Terminate command if running (like with --forget) and start it again.
37 =item -w, --wait
39 On first run, wait for the complete output.
41 =item -p, --pid
43 display PID
45 =item -q, --quiet
47 less verbose
49 =back
51 =head1 STATUS CODES
53 =over 4
55 =item B<115>
57 command started
59 =item B<114>
61 partial output shown
63 =item I<nnn>
65 called command returned with this status code I<nnn>
67 =back
69 =head1 LIMITS
71 If B<COMMAND> does not exit normally, but gets terminated by a signal,
72 the exit code is indistinguishable from a normal exit's status code,
73 due to bash(1) uses the value of 128+B<N> as the exit status
74 when a command terminates on a fatal signal B<N>.
76 =cut
78 EOF
81 set -e
82 set -o pipefail
83 set -u
85 print_partial()
87 cat "$dir/stdout"
90 warnx()
92 echo "${0##*/}: $*" >&2
95 verbose()
97 if [ $opt_quiet = no ]
98 then
99 "$@"
103 help()
105 pod2text "$0"
108 remove()
110 [ ! -e "$1" ] || command remove "$1"
113 opt_restart=no
114 opt_forget=no
115 opt_wait=no
116 opt_pid=no
117 opt_quiet=no
119 while [ $# -gt 0 ]
121 case "${1:-}" in
122 --restart|-r)
123 opt_restart=yes
124 opt_forget=yes
126 --forget|-f)
127 opt_forget=yes
129 --wait|-w)
130 opt_wait=yes
132 --pid|-p)
133 opt_pid=yes
135 --quiet|-q)
136 opt_quiet=yes
138 --help)
139 help
140 exit 0
143 shift
144 break
147 warnx "unknown option: $1"
148 exit -1
151 break
153 esac
154 shift
155 done
157 if [ $# = 0 ]
158 then
159 help
160 exit -1
163 declare -a command=("$@")
164 command_str=${command[*]}
165 commandhash=`echo "$command_str" | sha256sum | cut -f1 -d' '`
167 dir=~/.cache/partial/$commandhash
169 if [ $opt_pid = yes ]
170 then
171 cat "$dir/pid"
172 exit
175 if [ $opt_forget = yes ]
176 then
177 if [ -d "$dir" ]
178 then
179 pid=`cat "$dir/pid" 2>/dev/null || true`
180 if [ -n "$pid" ]
181 then
182 while kill -0 "$pid"
184 kill "$pid"
185 sleep 0.2
186 done
188 remove "$dir/pid"
189 remove "$dir/lock"
190 remove "$dir/stdout"
191 remove "$dir/running.lock"
192 remove "$dir/status"
193 remove "$dir/command.txt"
194 remove "$dir"
197 if [ $opt_restart = no ]
198 then
199 exit
203 mkdir -p "$dir"
205 exec {lockfd}>>"$dir/lock"
206 flock -x $lockfd
208 exec {runlockfd}>>"$dir/running.lock"
209 verbose warnx "state in $dir"
211 if flock -n -x $runlockfd
212 then
213 if [ -e "$dir/status" ]
214 then
215 verbose warnx "command finished: $(stat -c %y "$dir/status")"
216 print_partial
217 status=`cat "$dir/status"`
218 exit $status
219 else
220 echo "$command_str" > "$dir/command.txt"
222 if [ $opt_wait = yes ]
223 then
224 set +e
225 command "${command[@]}" | tee "$dir/stdout"
226 status=${PIPESTATUS[0]}
227 echo -n $status >"$dir/status"
229 exit $status
230 else
232 flock -u $lockfd
233 set +e
234 command "${command[@]}" > "$dir/stdout"
235 echo -n $? >"$dir/status"
238 echo $! > "$dir/pid"
239 verbose warnx "command started"
241 exit 115
244 else
245 flock -u $runlockfd
247 verbose warnx "command is in progress since $(stat -c %y "$dir/command.txt"), partial output follows."
248 print_partial
249 exit 114