+def run_and_grep(cmd, read_output, *regexps,
+ encoding=locale.getpreferredencoding(), **popen_kwargs):
+ """Run a subprocess and capture output lines matching regexps.
+
+ Arguments:
+ * cmd: The command to run, as a list or string, as for subprocess.Popen.
+ * read_output: 'stdout' or 'stderr', the name of the output stream to read.
+ Remaining arguments are regexps to match output, as strings or compiled
+ regexp objects. Output lines matching any regexp will be captured.
+
+ Keyword arguments:
+ * encoding: The encoding used to decode the subprocess output.
+ Remaining keyword arguments are passed directly to subprocess.Popen.
+
+ Returns 2-tuple (subprocess returncode, list of matched output lines).
+ """
+ regexps = [regexp if hasattr(regexp, 'search') else re.compile(regexp)
+ for regexp in regexps]
+ popen_kwargs[read_output] = subprocess.PIPE
+ proc = subprocess.Popen(cmd, **popen_kwargs)
+ with open(getattr(proc, read_output).fileno(), encoding=encoding) as output:
+ matched_lines = []
+ for line in output:
+ if any(regexp.search(line) for regexp in regexps):
+ matched_lines.append(line)
+ if read_output == 'stderr':
+ print(line, file=sys.stderr, end='')
+ return proc.wait(), matched_lines
+
+