1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
|
PW(1) Pipe Watch PW(1)
NAME
pw - Pipe Watch: monitor recent lines of output from pipe
SYNOPSIS
command | pw [-i interval] [-l interval] [-n number-of-lines] [-d]
DESCRIPTION
pw stands for Pipe Watch. This is a utility which continuously reads textual input from a
pipe or pipe-like source, and maintains a dynamic display of the most recently read N
lines.
If pw is invoked such that its standard input is a TTY, it simply reads lines and prints
them in its characteristic way, with control characters replaced by caret codes, until
end-of-file is encountered. Long lines aren't clipped, and there is no interactive mode.
The intended use of pw is that its standard input is a pipe, such as the output of another
command, or a pipe-like device such as a socket or whatever. In this situation, pw ex-
pects to be executed in a TTY session in which a /dev/tty device can be opened, for the
purposes of obtaining interactive input. The remaining description pertains to this in-
teractive mode.
In interactive mode, pw simultaneously monitors its standard input for the arrival of new
data, as well as the TTY for interactive commands. Lines from standard input are placed
into a FIFO buffer. While the FIFO buffer is not yet full, lines are displayed immedi-
ately. After the FIFO buffer fills up with the specified number of lines (controlled by
the -n option) then pw transitions into a mode in which, old lines are bumped from the
tail of the FIFO as new ones are added to the head, and refresh operations are required in
order to display the current FIFO contents.
The display only refreshes with the latest FIFO data when
1. there is some keyboard activity from the terminal; or
2. when the interval period has expired without new input having been seen; or else
3. whenever the long period elapses.
In other words, while the pipe is spewing, and there is no keyboard input, the display is
updated infrequently, only according to the long interval.
The display is also updated when standard input indicates end-of-data. In this situation,
pw terminates, unless the -d (do not quit) option has been specified, in which case it pw
stays in interactive mode. The the end-of-data status is indicated by the string EOF being
displayed in the status line after the data.
DISPLAY
Lines displayed by pw are trimmed not to exceed the number of terminal columns. When a
line is trimmed, it is terminated by the < character to indicate that there are more char-
acters. The display may be scrolled interactively to read the long lines.
The ASCII DEL character (127) is displayed as ^? and ASCII control characters are dis-
played as ^@, ^A, ... ^Z, ... ^_. All other characters are sent to the display as-is.
No attempt is made to account for the width of East Asian Unicode characters, and such.
When the display is scrolled horizontally, the > character appears at the start of each
line to indicate this state. Thus, if neither end of a long line is currently visible,
then its visible portion appears delimited by >...<.
COMMANDS
When pw enters closed loop operation, the following single-key commands are available:
q, Ctrl-C
Quit the program.
l, Left Arrow
Scroll the display to the left.
h, Right Arrow
Scroll the display to the right.
0, Home
Reset scroll to first column.
Space Suspend the refresh of the display. In suspended mode, input continues to pass
through the FIFO, but all display refresh is stopped. The status indicator SUS-
PENDED is displayed below the data. If the the status is already EOF then suspend
mode cannot be entered.
Enter Cancel suspended mode, resuming display refresh. The display is refreshed immedi-
ately and the SUSPENDED status indicator disappears.
: Enter colon command mode. In colon command mode, the status line clears and a colon
prompt appears there. An extended command can be entered. Pressing Enter in colon
mode dispatches the command. Simple editing is available: backspace, Ctrl-W word
erase and Ctrl-U line erase. If backspace is used in an empty colon line, colon
mode terminates without executing a command. Ctrl-C and Esc also terminate colon
mode without executing a command. Colon commands are documented in the COLON COM-
MANDS section below.
/pattern, ?pattern
Activate trigger mode if a non-empty pattern is specified, or else cancel trigger
mode if an empty pattern is specified. The / command specifies head trigger mode,
whereas ? specifies tail trigger mode. Under head trigger mode, the display re-
freshes only when the most recent line ("head line") in the FIFO matches the speci-
fied pattern. The head line is the one which will appear at the bottom of the dis-
play, since newer lines appear at the bottom and scroll out toward the top. In
head trigger mode, the status string TRIG (/pattern) appears, showing the pattern
preceded by a slash. Under tail trigger mode, the display refreshes only when the
least recent line ("tail line") in the FIFO matches the specified pattern. That
line is the one which will appear at the top of the display. In tail trigger mode,
the status string TRIG (?pattern) appears, showing the pattern preceded by a ques-
tion mark. The pattern is an extended regular expression (ERE). Trigger patterns
saved in a history which may be navigated for recall using the up and down arrow
keys or Ctrl-P and Ctrl-N.
Ctrl-Z Suspends pw, and indeed the entire surrounding process group, to the background to
gain shell access. This requires a job control shell. When pw is foregrounded
again, it will refresh the display in a new text area below the cursor, avoiding
overwriting anything in the terminal. Thus suspending and then immediately fore-
grounding provides a way to save a snapshot of the window into the terminal ses-
sions history.
COLON COMMANDS
First, some general remarks. Display refresh doesn't pause during the editing of a colon
command. If that is required, the suspend command must be used. The space between the
command and the argument may be omitted. After a command is executed, a result message ap-
pears in its place. This message persists over the poll interval period. The longer the
poll interval (-i option), the longer the result message persists.
Colon commands are saved in a history which may be navigated for recall using the up and
down arrow keys or Ctrl-P and Ctrl-N.
:w filename
Write the current contents of the display into the specified file.
:a filename
Append the current contents of the display into the specified file.
:! filename
Pipe the current contents of of the display into the specified command.
:g pattern, :v pattern
Push a grep pattern onto the grep stack. The :g command pushes a plain pattern; the
:v command pushes a logically inverted pattern. The grep stack holds up to 64 pat-
terns, which are extended regular expressions (EREs). If the pattern is success-
fully pushed onto the stack, it restricts which lines are admitted into the FIFO
and available for display. The plain pattern admits only the lines which match
pattern; the inverted pattern admits only lines which do not match pattern. Lines
which are already in the FIFO at the time a new pattern is introduced are not af-
fected. The status line shows GREP (pattern[, ...]) to indicate that grep mode is
in effect, and gives the list of patterns, separated by commas. The inverted pat-
terns are indicated by a leading ! character.
:r[!] Remove and forget the most recent grep pattern (:gor:v) from the grep stack. If the
stack depth decrements from 1, the grep mode is disabled and the GREP status line
disappears. If the optional ! modifier is included in the command, then it pops
the entire stack, forgetting all the patterns and disabling grep mode.
Any other command results in a brief error message.
OPTIONS
-i real
Set the poll interval to number of seconds specified by real. This is is a float-
ing-point constant such as 3 or 1.5. Exponential notation such as 5E-1 (equivalent
to 0.5) is permitted. This interval determines the input poll timeout of pw's in-
put processing loop. If no data arrives from the primary input, or from the TTY for
this amount of time, a timeout occurs, and the display is refreshed if the FIFO has
changed since the last refresh. The default poll interval is 1s.
-l real
Set the long update interval to number of seconds specified by real. The format is
the same as -i, and the default value is 10s. Every time the long update interval
passes, the display is updated, if the FIFO has changed since the last update.
This happens even when input is arriving too rapidly to permit the poll timeout to
take place. The purpose of the long interval is to ensure that there are updates
even when the data source continuously and rapidly produces data, and there is no
TTY input activity. The long interval should be at least several times longer than
the short interval. The granularity of the timing of the long interval updates de-
pends on the poll interval; in the absence of TTY input, pw will not perform any
display updates more often that the poll interval, even if the long interval is
made smaller than the poll interval.
-n integer
Set the number of lines N to the specified decimal integer value. The default value
is 15. This value must be positive, and is clipped to the number of display lines
available in the terminal, less one.
-d Disable auto-quit: when no more input is available, instead of updating the display
one last time and terminating, pw will updating the status to EOF and staying in
the interactive mode. This is useful when the last portion of the input is of in-
terest, and contains long lines that require horizontal scrolling.
TERMINATION STATUS
If pw reaches EOF on standard input without encountering a read error, then its termina-
tion status will be successful. This is regardless of whether it automatically quits, or
whether it stays in interactive mode and then quits due to a quit command. If the data
ends prematurely due to a read error, or if the program is asked to quit before all of the
data has been read, then unsuccessful termination status will be indicated.
Incorrect usage, such as nonexistent options or bad arguments to options, result in a di-
agnostic on standard error and an unsuccessful termination.
Unexpected conditions like out of memory result in abnormal termination (abort).
BUGS
This was written over the course of a couple of hours, and tested only interactively.
The program doesn't respond to window size changes. The display format, such as the han-
dling of control characters, is hard-coded.
The program uses hard-coded ANSI sequences, so it doesn't support interesting old termi-
nals. On the other hand, it carries no dependency on any terminal abstraction li-
brary/data.
The intervals and number of lines cannot be dynamically adjusted.
There is no support for unwrapping long lines, which would be useful for copy and paste.
During the :! command's execution, the TTY settings are not restored.
Most of these issues are easy; patches welcome.
AUTHOR
Kaz Kylheku <kaz@kylheku.com>
COPYRIGHT
Copyright 2022, BSD2 License.
Utility Commands 26 April 2022 PW(1)
|