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
This commit is contained in:
parent
5f4074a250
commit
b2bfd76b06
1
NEWS
1
NEWS
@ -9,6 +9,7 @@ procps-ng-NEXT
|
|||||||
* vmstat: Referesh memory statistics Debian #1027963
|
* vmstat: Referesh memory statistics Debian #1027963
|
||||||
* w: Add --pids option merge #159
|
* w: Add --pids option merge #159
|
||||||
* watch: Pass through beep issue #104
|
* watch: Pass through beep issue #104
|
||||||
|
* watch: -r option to not re-exec on SIGWINCH merge #125
|
||||||
|
|
||||||
procps-ng-4.0.2
|
procps-ng-4.0.2
|
||||||
---------------
|
---------------
|
||||||
|
50
man/watch.1
50
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
|
.SH NAME
|
||||||
watch \- execute a program periodically, showing output fullscreen
|
watch \- execute a program periodically, showing output fullscreen
|
||||||
.SH SYNOPSIS
|
.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.
|
\fIcommand\fR is run every 2 seconds and \fBwatch\fR will run until interrupted.
|
||||||
.SH OPTIONS
|
.SH OPTIONS
|
||||||
.TP
|
.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]
|
\fB\-d\fR, \fB\-\-differences\fR[=\fIpermanent\fR]
|
||||||
Highlight the differences between successive updates. If the optional
|
Highlight the differences between successive updates. If the optional
|
||||||
\fIpermanent\fR argument is specified then
|
\fIpermanent\fR argument is specified then
|
||||||
.B watch
|
.B watch
|
||||||
will show all changes since the first iteration.
|
will show all changes since the first iteration.
|
||||||
.TP
|
.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
|
\fB\-n\fR, \fB\-\-interval\fR \fIseconds\fR
|
||||||
Specify update interval. The command will not allow quicker than 0.1 second
|
Specify update interval. The command will not allow quicker than 0.1 second
|
||||||
interval, in which the smaller values are converted. Both '.' and ',' work
|
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
|
(if present) and notice how the fractional seconds stays (nearly) the same, as opposed to
|
||||||
normal mode where they continuously increase.
|
normal mode where they continuously increase.
|
||||||
.TP
|
.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>
|
\fB\-q\fR, \fB\-\-equexit\fR <cycles>
|
||||||
Exit when output of
|
Exit when output of
|
||||||
.I command
|
.I command
|
||||||
does not change for the given number of cycles.
|
does not change for the given number of cycles.
|
||||||
.TP
|
.TP
|
||||||
\fB\-c\fR, \fB\-\-color\fR
|
\fB\-r\fR, \fB\-\-no-rerun\fR
|
||||||
Interpret ANSI color and style sequences.
|
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
|
.TP
|
||||||
\fB\-x\fR, \fB\-\-exec\fR
|
\fB\-x\fR, \fB\-\-exec\fR
|
||||||
Pass
|
Pass
|
||||||
@ -70,9 +77,6 @@ instead of
|
|||||||
.B sh \-c
|
.B sh \-c
|
||||||
which reduces the need to use extra quoting to get the desired effect.
|
which reduces the need to use extra quoting to get the desired effect.
|
||||||
.TP
|
.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
|
\fB\-h\fR, \fB\-\-help\fR
|
||||||
Display help text and exit.
|
Display help text and exit.
|
||||||
.TP
|
.TP
|
||||||
@ -134,7 +138,9 @@ itself.
|
|||||||
Upon terminal resize, the screen will not be correctly repainted until the
|
Upon terminal resize, the screen will not be correctly repainted until the
|
||||||
next scheduled update. All
|
next scheduled update. All
|
||||||
.B \-\-differences
|
.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
|
Non-printing characters are stripped from program output. Use \fBcat -v\fR as
|
||||||
part of the command pipeline if you want to see them.
|
part of the command pipeline if you want to see them.
|
||||||
|
40
src/watch.c
40
src/watch.c
@ -72,6 +72,7 @@ static int flags;
|
|||||||
#define WATCH_ERREXIT (1 << 6)
|
#define WATCH_ERREXIT (1 << 6)
|
||||||
#define WATCH_CHGEXIT (1 << 7)
|
#define WATCH_CHGEXIT (1 << 7)
|
||||||
#define WATCH_EQUEXIT (1 << 8)
|
#define WATCH_EQUEXIT (1 << 8)
|
||||||
|
#define WATCH_NORERUN (1 << 9)
|
||||||
|
|
||||||
static int curses_started = 0;
|
static int curses_started = 0;
|
||||||
static long height = 24, width = 80;
|
static long height = 24, width = 80;
|
||||||
@ -101,6 +102,7 @@ static void __attribute__ ((__noreturn__))
|
|||||||
" exit when output from command does not change\n"), out);
|
" exit when output from command does not change\n"), out);
|
||||||
fputs(_(" -n, --interval <secs> seconds to wait between updates\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(_(" -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(_(" -t, --no-title turn off header\n"), out);
|
||||||
fputs(_(" -w, --no-wrap turn off line wrapping\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);
|
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;
|
||||||
char **command_argv;
|
char **command_argv;
|
||||||
int command_length = 0; /* not including final \0 */
|
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
|
watch_usec_t next_loop; /* next loop time in us, used for precise time
|
||||||
* keeping only */
|
* keeping only */
|
||||||
#ifdef WITH_WATCH8BIT
|
#ifdef WITH_WATCH8BIT
|
||||||
@ -832,6 +835,7 @@ int main(int argc, char *argv[])
|
|||||||
{"equexit", required_argument, 0, 'q'},
|
{"equexit", required_argument, 0, 'q'},
|
||||||
{"exec", no_argument, 0, 'x'},
|
{"exec", no_argument, 0, 'x'},
|
||||||
{"precise", no_argument, 0, 'p'},
|
{"precise", no_argument, 0, 'p'},
|
||||||
|
{"no-rerun", no_argument, 0, 'r'},
|
||||||
{"no-title", no_argument, 0, 't'},
|
{"no-title", no_argument, 0, 't'},
|
||||||
{"no-wrap", no_argument, 0, 'w'},
|
{"no-wrap", no_argument, 0, 'w'},
|
||||||
{"version", no_argument, 0, 'v'},
|
{"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"));
|
interval = strtod_nol_or_err(interval_string, _("Could not parse interval from WATCH_INTERVAL"));
|
||||||
|
|
||||||
while ((optc =
|
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) {
|
!= EOF) {
|
||||||
switch (optc) {
|
switch (optc) {
|
||||||
case 'b':
|
case 'b':
|
||||||
@ -875,6 +879,9 @@ int main(int argc, char *argv[])
|
|||||||
flags |= WATCH_EQUEXIT;
|
flags |= WATCH_EQUEXIT;
|
||||||
max_cycles = strtod_nol_or_err(optarg, _("failed to parse argument"));
|
max_cycles = strtod_nol_or_err(optarg, _("failed to parse argument"));
|
||||||
break;
|
break;
|
||||||
|
case 'r':
|
||||||
|
flags |= WATCH_NORERUN;
|
||||||
|
break;
|
||||||
case 't':
|
case 't':
|
||||||
show_title = 0;
|
show_title = 0;
|
||||||
break;
|
break;
|
||||||
@ -990,18 +997,25 @@ int main(int argc, char *argv[])
|
|||||||
output_header(command, interval);
|
output_header(command, interval);
|
||||||
#endif /* WITH_WATCH8BIT */
|
#endif /* WITH_WATCH8BIT */
|
||||||
|
|
||||||
int exit = run_command(command, command_argv);
|
if (!(flags & WATCH_NORERUN) ||
|
||||||
if (flags & WATCH_EQUEXIT) {
|
get_time_usec() - last_run > interval * USECS_PER_SEC) {
|
||||||
if (cycle_count == max_cycles && exit) {
|
last_run = get_time_usec();
|
||||||
break;
|
int exit = run_command(command, command_argv);
|
||||||
} else if (exit) {
|
|
||||||
cycle_count++;
|
if (flags & WATCH_EQUEXIT) {
|
||||||
} else {
|
if (cycle_count == max_cycles && exit) {
|
||||||
cycle_count = 0;
|
break;
|
||||||
}
|
} else if (exit) {
|
||||||
} else if (exit) {
|
cycle_count++;
|
||||||
break;
|
} else {
|
||||||
}
|
cycle_count = 0;
|
||||||
|
}
|
||||||
|
} else if (exit) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
refresh();
|
||||||
|
}
|
||||||
|
|
||||||
if (precise_timekeeping) {
|
if (precise_timekeeping) {
|
||||||
watch_usec_t cur_time = get_time_usec();
|
watch_usec_t cur_time = get_time_usec();
|
||||||
|
Loading…
Reference in New Issue
Block a user