]> granicus.if.org Git - procps-ng/commitdiff
watch: exit when command output changes.
authorKent R. Spillner <kspillner@acm.org>
Thu, 26 Jan 2012 14:42:37 +0000 (08:42 -0600)
committerKent R. Spillner <kspillner@acm.org>
Thu, 26 Jan 2012 14:42:37 +0000 (08:42 -0600)
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
watch.c

diff --git a/watch.1 b/watch.1
index 1e82340387535f5c284b837f367b3f59721ff30b..41a86f4773db9cc89741c4e9ec6fd255f869cc97 100644 (file)
--- 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 0bb6239125838ef253d6cff1a1fe2bcc883d2c57..2c4a4b0473c12d6cba8a9b2cafdb2efdf28b36ee 100644 (file)
--- 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 <secs>  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();