From 81f64657ba183ee983ea98c7f97904296b2ce5aa Mon Sep 17 00:00:00 2001 From: "Kent R. Spillner" Date: Thu, 26 Jan 2012 08:42:37 -0600 Subject: [PATCH] watch: exit when command output changes. Add new flags to watch (-g/--chgexit) so that it exits when the output changes. This is useful in builds and shell scripts, for example when deploying webapps to block the remainder of the deployment steps until after the webapp starts. e.g. watch --chgexit curl http://foo/bar --- watch.1 | 6 ++++++ watch.c | 25 +++++++++++++++++++++---- 2 files changed, 27 insertions(+), 4 deletions(-) diff --git a/watch.1 b/watch.1 index 1e823403..41a86f47 100644 --- a/watch.1 +++ b/watch.1 @@ -11,6 +11,7 @@ runs repeatedly, displaying its output and errors (the first screenfull). This allows you to watch the program output change over time. By default, the program is run every 2 seconds. +By default, .B watch will run until interrupted. .SH OPTIONS @@ -44,6 +45,11 @@ Beep if command has a non-zero exit. \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\-c\fR, \fB\-\-color\fR Interpret ANSI color sequences. .TP diff --git a/watch.c b/watch.c index 0bb62391..2c4a4b04 100644 --- a/watch.c +++ b/watch.c @@ -69,6 +69,7 @@ static void __attribute__ ((__noreturn__)) " -c, --color interpret ANSI color sequences\n" " -d, --differences highlight changes between updates\n" " -e, --errexit exit if command has a non-zero exit\n" + " -g, --chgexit exit when output from command changes\n" " -n, --interval seconds to wait between updates\n" " -p, --precise attempt run command in precise intervals\n" " -t, --no-title turn off header\n" @@ -277,7 +278,7 @@ int main(int argc, char *argv[]) option_exec = 0, option_beep = 0, option_color = 0, - option_errexit = 0, option_help = 0, option_version = 0; + option_errexit = 0, option_chgexit = 0, option_help = 0, option_version = 0; double interval = 2; char *command; char **command_argv; @@ -292,6 +293,7 @@ int main(int argc, char *argv[]) int pipefd[2]; int status; + int exit_early = 0; pid_t child; static struct option longopts[] = { @@ -301,6 +303,7 @@ int main(int argc, char *argv[]) {"interval", required_argument, 0, 'n'}, {"beep", no_argument, 0, 'b'}, {"errexit", no_argument, 0, 'e'}, + {"chgexit", no_argument, 0, 'g'}, {"exec", no_argument, 0, 'x'}, {"precise", no_argument, 0, 'p'}, {"no-title", no_argument, 0, 't'}, @@ -314,7 +317,7 @@ int main(int argc, char *argv[]) textdomain(PACKAGE); while ((optc = - getopt_long(argc, argv, "+bced::hn:pvtx", longopts, (int *)0)) + getopt_long(argc, argv, "+bced::ghn:pvtx", longopts, (int *)0)) != EOF) { switch (optc) { case 'b': @@ -331,6 +334,9 @@ int main(int argc, char *argv[]) case 'e': option_errexit = 1; break; + case 'g': + option_chgexit = 1; + break; case 't': show_title = 0; break; @@ -425,7 +431,7 @@ int main(int argc, char *argv[]) if (precise_timekeeping) next_loop = get_time_usec(); - for (;;) { + do { time_t t = time(NULL); char *ts = ctime(&t); int tsl = strlen(ts); @@ -636,6 +642,17 @@ int main(int argc, char *argv[]) tabpending = 0; } move(y, x); + if (!exit_early && option_chgexit) { +#ifdef WITH_WATCH8BIT + cchar_t oldc; + in_wch(&oldc); + exit_early = (wchar_t) c != oldc.chars[0]; +#else + chtype oldch = inch(); + unsigned char oldc = oldch & A_CHARTEXT; + exit_early = (unsigned char) c != oldc; +#endif /* WITH_WATCH8BIT */ + } if (option_differences) { #ifdef WITH_WATCH8BIT cchar_t oldc; @@ -705,7 +722,7 @@ int main(int argc, char *argv[]) usleep(next_loop - cur_time); } else usleep(interval * 1000000); - } + } while (!exit_early); endwin();