summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCraig Small <csmall@dropbear.xyz>2023-01-17 20:45:48 +1100
committerCraig Small <csmall@dropbear.xyz>2023-01-17 20:45:48 +1100
commitb2bfd76b06efc8c8b2a9d4b2d7d20c19b50a6fb4 (patch)
tree2c8551b0e8251d30cf08432a31ffab0a2ffeddba
parent5f4074a250a58ca53da42faf485072730d2fe9cf (diff)
downloadprocps-ng-b2bfd76b06efc8c8b2a9d4b2d7d20c19b50a6fb4.tar.gz
watch: add -r to not rexec on terminal resize
If you have the watched program doing some other thing every time its run and you resize the window, you might get unexpected results. The -r option lets you run only when the interval has expired. References: procps-ng/procps!125 procps-ng/procps#190
-rw-r--r--NEWS1
-rw-r--r--man/watch.150
-rw-r--r--src/watch.c40
3 files changed, 56 insertions, 35 deletions
diff --git a/NEWS b/NEWS
index bb664d9..c319ad5 100644
--- a/NEWS
+++ b/NEWS
@@ -9,6 +9,7 @@ procps-ng-NEXT
* vmstat: Referesh memory statistics Debian #1027963
* w: Add --pids option merge #159
* watch: Pass through beep issue #104
+ * watch: -r option to not re-exec on SIGWINCH merge #125
procps-ng-4.0.2
---------------
diff --git a/man/watch.1 b/man/watch.1
index d130ef7..2007e4f 100644
--- a/man/watch.1
+++ b/man/watch.1
@@ -1,4 +1,4 @@
-.TH WATCH 1 "2023-01-16" "procps-ng" "User Commands"
+.TH WATCH 1 "2023-01-17" "procps-ng" "User Commands"
.SH NAME
watch \- execute a program periodically, showing output fullscreen
.SH SYNOPSIS
@@ -13,12 +13,26 @@ allows you to watch the program output change over time. By default,
\fIcommand\fR is run every 2 seconds and \fBwatch\fR will run until interrupted.
.SH OPTIONS
.TP
+\fB\-b\fR, \fB\-\-beep\fR
+Beep if command has a non-zero exit.
+.TP
+\fB\-c\fR, \fB\-\-color\fR
+Interpret ANSI color and style sequences.
+.TP
\fB\-d\fR, \fB\-\-differences\fR[=\fIpermanent\fR]
Highlight the differences between successive updates. If the optional
\fIpermanent\fR argument is specified then
.B watch
will show all changes since the first iteration.
.TP
+\fB\-e\fR, \fB\-\-errexit\fR
+Freeze updates on command error, and exit after a key press.
+.TP
+\fB\-g\fR, \fB\-\-chgexit\fR
+Exit when the output of
+.I command
+changes.
+.TP
\fB\-n\fR, \fB\-\-interval\fR \fIseconds\fR
Specify update interval. The command will not allow quicker than 0.1 second
interval, in which the smaller values are converted. Both '.' and ',' work
@@ -38,28 +52,21 @@ Try it with
(if present) and notice how the fractional seconds stays (nearly) the same, as opposed to
normal mode where they continuously increase.
.TP
-\fB\-t\fR, \fB\-\-no\-title\fR
-Turn off the header showing the interval, command, and current time at the
-top of the display, as well as the following blank line.
-.TP
-\fB\-b\fR, \fB\-\-beep\fR
-Beep if command has a non-zero exit.
-.TP
-\fB\-e\fR, \fB\-\-errexit\fR
-Freeze updates on command error, and exit after a key press.
-.TP
-\fB\-g\fR, \fB\-\-chgexit\fR
-Exit when the output of
-.I command
-changes.
-.TP
\fB\-q\fR, \fB\-\-equexit\fR <cycles>
Exit when output of
.I command
does not change for the given number of cycles.
.TP
-\fB\-c\fR, \fB\-\-color\fR
-Interpret ANSI color and style sequences.
+\fB\-r\fR, \fB\-\-no-rerun\fR
+Do not run the program on terminal resize, the output of the program will re-appear at the next
+regular run time.
+.TP
+\fB\-t\fR, \fB\-\-no\-title\fR
+Turn off the header showing the interval, command, and current time at the
+top of the display, as well as the following blank line.
+.TP
+\fB\-w\fR, \fB\-\-no\-wrap\fR
+Turn off line wrapping. Long lines will be truncated instead of wrapped to the next line.
.TP
\fB\-x\fR, \fB\-\-exec\fR
Pass
@@ -70,9 +77,6 @@ instead of
.B sh \-c
which reduces the need to use extra quoting to get the desired effect.
.TP
-\fB\-w\fR, \fB\-\-no\-wrap\fR
-Turn off line wrapping. Long lines will be truncated instead of wrapped to the next line.
-.TP
\fB\-h\fR, \fB\-\-help\fR
Display help text and exit.
.TP
@@ -134,7 +138,9 @@ itself.
Upon terminal resize, the screen will not be correctly repainted until the
next scheduled update. All
.B \-\-differences
-highlighting is lost on that update as well.
+highlighting is lost on that update as well. When using the
+.B \-\-no\-rerun
+option, no output of will be visible.
Non-printing characters are stripped from program output. Use \fBcat -v\fR as
part of the command pipeline if you want to see them.
diff --git a/src/watch.c b/src/watch.c
index c65f69b..b7ad005 100644
--- a/src/watch.c
+++ b/src/watch.c
@@ -72,6 +72,7 @@ static int flags;
#define WATCH_ERREXIT (1 << 6)
#define WATCH_CHGEXIT (1 << 7)
#define WATCH_EQUEXIT (1 << 8)
+#define WATCH_NORERUN (1 << 9)
static int curses_started = 0;
static long height = 24, width = 80;
@@ -101,6 +102,7 @@ static void __attribute__ ((__noreturn__))
" exit when output from command does not change\n"), out);
fputs(_(" -n, --interval <secs> seconds to wait between updates\n"), out);
fputs(_(" -p, --precise attempt run command in precise intervals\n"), out);
+ fputs(_(" -r, --no-rerun do not rerun program on window resize\n"), out);
fputs(_(" -t, --no-title turn off header\n"), out);
fputs(_(" -w, --no-wrap turn off line wrapping\n"), out);
fputs(_(" -x, --exec pass command to exec instead of \"sh -c\"\n"), out);
@@ -814,6 +816,7 @@ int main(int argc, char *argv[])
char *command;
char **command_argv;
int command_length = 0; /* not including final \0 */
+ watch_usec_t last_run = 0;
watch_usec_t next_loop; /* next loop time in us, used for precise time
* keeping only */
#ifdef WITH_WATCH8BIT
@@ -832,6 +835,7 @@ int main(int argc, char *argv[])
{"equexit", required_argument, 0, 'q'},
{"exec", no_argument, 0, 'x'},
{"precise", no_argument, 0, 'p'},
+ {"no-rerun", no_argument, 0, 'r'},
{"no-title", no_argument, 0, 't'},
{"no-wrap", no_argument, 0, 'w'},
{"version", no_argument, 0, 'v'},
@@ -851,7 +855,7 @@ int main(int argc, char *argv[])
interval = strtod_nol_or_err(interval_string, _("Could not parse interval from WATCH_INTERVAL"));
while ((optc =
- getopt_long(argc, argv, "+bced::ghq:n:pvtwx", longopts, (int *)0))
+ getopt_long(argc, argv, "+bced::ghq:n:prtwvx", longopts, (int *)0))
!= EOF) {
switch (optc) {
case 'b':
@@ -875,6 +879,9 @@ int main(int argc, char *argv[])
flags |= WATCH_EQUEXIT;
max_cycles = strtod_nol_or_err(optarg, _("failed to parse argument"));
break;
+ case 'r':
+ flags |= WATCH_NORERUN;
+ break;
case 't':
show_title = 0;
break;
@@ -990,18 +997,25 @@ int main(int argc, char *argv[])
output_header(command, interval);
#endif /* WITH_WATCH8BIT */
- int exit = run_command(command, command_argv);
- if (flags & WATCH_EQUEXIT) {
- if (cycle_count == max_cycles && exit) {
- break;
- } else if (exit) {
- cycle_count++;
- } else {
- cycle_count = 0;
- }
- } else if (exit) {
- break;
- }
+ if (!(flags & WATCH_NORERUN) ||
+ get_time_usec() - last_run > interval * USECS_PER_SEC) {
+ last_run = get_time_usec();
+ int exit = run_command(command, command_argv);
+
+ if (flags & WATCH_EQUEXIT) {
+ if (cycle_count == max_cycles && exit) {
+ break;
+ } else if (exit) {
+ cycle_count++;
+ } else {
+ cycle_count = 0;
+ }
+ } else if (exit) {
+ break;
+ }
+ } else {
+ refresh();
+ }
if (precise_timekeeping) {
watch_usec_t cur_time = get_time_usec();