diff --git a/docs/pv.1 b/docs/pv.1 index 81980ed..6c5d97d 100644 --- a/docs/pv.1 +++ b/docs/pv.1 @@ -13,6 +13,8 @@ pv \- monitor and manage the progress of data through a pipe \fBpv\fR \fB\-R\fR|\fB\-\-remote\fR \fIPID\fR [\fIOPTION\fR]... .PP \fBpv\fR \fB\-Q\fR|\fB\-\-query\fR \fIPID\fR [\fIOPTION\fR]... +.PP +\fBpv\fR [\fIOPTION\fR]... \fB\-M\fR|\fB\-\-monitor\fR \-\- \fICOMMAND\fR [\fIARGS\fR]... .\" .SH DESCRIPTION Show the progress of data through a pipeline by giving information such as @@ -27,6 +29,9 @@ read. .PP In \*(lq\fB\-\-watchfd\fR\*(rq mode, inspect another process and show its progress through the files it has open. +.PP +In \*(lq\fB\-\-monitor\fR\*(rq mode, run a command and display the progress +of data through both its standard input and its standard output. .\" .SH OPTIONS .\" @@ -409,6 +414,20 @@ they match those of that process - such as \*(lq\fB\-\-null\fR\*(rq, and \*(lq\fB\-\-average\-rate\-window\fR\*(rq. Data transfer modifiers will have no effect. +.TP +.B \-M, \-\-monitor +Run the command specified by the remaining arguments, and monitor its +standard input and standard output. +Use \*(lq\fB\-\-\fR\*(rq after all of the \fBpv\fR options to keep the +command's options separate. +.IP +For example, \*(lq\fBpv\~\-\-cursor\~\-\-monitor\~\-\-\~gzip\~\-9\fR\*(rq is +equivalent to +\*(lq\fBpv\~\-\-cursor\~|\~gzip\~\-9\~|\~pv\~\-\-cursor\fR\*(rq, except that +the latter can't show the input:output ratio. +.\"TODO: choice of displaying two progress bars (in + out) or only one +.\"TODO: formatting option for input:output ratio +.\"TODO: a way to specify the name of each bar, if there are two .\" .SS "Other options" .TP diff --git a/src/include/options.h b/src/include/options.h index 2b339d8..366cc50 100644 --- a/src/include/options.h +++ b/src/include/options.h @@ -32,7 +32,8 @@ typedef enum { PV_ACTION_STORE_AND_FORWARD, /* store to file, then output from it */ PV_ACTION_WATCHFD, /* watch process file descriptors */ PV_ACTION_REMOTE_CONTROL, /* remotely control another pv */ - PV_ACTION_QUERY /* watch the state of another pv */ + PV_ACTION_QUERY, /* watch the state of another pv */ + PV_ACTION_MONITOR /* run a process, watch its stdin/out */ } pvaction_t; /* diff --git a/src/main/help.c b/src/main/help.c index 8c67489..07837e9 100644 --- a/src/main/help.c +++ b/src/main/help.c @@ -372,6 +372,9 @@ void display_help(void) N_("show progress of process PID"), { 0, 0, 0, 0} }, #endif /* PV_REMOTE_CONTROL */ + { "-M", "--monitor", NULL, + N_("monitor the input and output of a command"), + { 0, 0, 0, 0} }, { "", NULL, NULL, NULL, { 0, 0, 0, 0} }, { "-P", "--pidfile", N_("FILE"), N_("save process ID in FILE"), diff --git a/src/main/main.c b/src/main/main.c index 816287e..c71c26b 100644 --- a/src/main/main.c +++ b/src/main/main.c @@ -560,6 +560,11 @@ int main(int argc, char **argv) /* Query the progress of another running pv. */ retcode = pv_query_loop(state, opts->query); break; + case PV_ACTION_MONITOR: + /* Run a process and monitor its input and output. */ + /* TODO: run the monitor action. */ + retcode = 1; + break; } /* Clear up the PID file, if one was written. */ diff --git a/src/main/options.c b/src/main/options.c index f49a676..ce3b192 100644 --- a/src/main/options.c +++ b/src/main/options.c @@ -680,6 +680,7 @@ opts_t opts_parse(unsigned int argc, char **argv) { "watchfd", 1, NULL, (int) 'd' }, { "output", 1, NULL, (int) 'o' }, { "average-rate-window", 1, NULL, (int) 'm' }, + { "monitor", 0, NULL, (int) 'M' }, #ifdef ENABLE_DEBUGGING { "debug", 1, NULL, (int) '!' }, #endif /* ENABLE_DEBUGGING */ @@ -688,7 +689,7 @@ opts_t opts_parse(unsigned int argc, char **argv) /*@+nullassign@ */ int option_index = 0; #endif /* HAVE_GETOPT_LONG */ - char *short_options = "hVpteIrab8kTA:fvnqcWD:s:gl0i:w:H:N:u:F:x:L:B:CEZ:SYKOXU:R:Q:P:d:m:o:" + char *short_options = "hVpteIrab8kTA:fvnqcWD:s:gl0i:w:H:N:u:F:x:L:B:CEZ:SYKOXU:R:Q:P:d:m:o:M" #ifdef ENABLE_DEBUGGING "!:" #endif @@ -1102,6 +1103,9 @@ opts_t opts_parse(unsigned int argc, char **argv) case 'm': opts->average_rate_window = pv_getnum_count(optarg, opts->decimal_units); break; + case 'M': + opts->action = PV_ACTION_MONITOR; + break; #ifdef ENABLE_DEBUGGING case '!': debugging_output_destination(optarg); @@ -1250,6 +1254,18 @@ opts_t opts_parse(unsigned int argc, char **argv) /*@+mustfreefresh@ */ } + /* + * At least one non-option argument is required with -M. + */ + if ((PV_ACTION_MONITOR == opts->action) && (optind >= (int) argc)) { + /*@-mustfreefresh@ *//* see above */ + fprintf(stderr, "%s: -M: %s\n", opts->program_name, + _("a command to run must be specified")); + opts_free(opts); + return NULL; + /*@+mustfreefresh@ */ + } + /* * Store remaining command-line arguments. */