]> err.no Git - moreutils/commitdiff
curiouscat: New command to grep output of commands
authorTollef Fog Heen <tollef.fog.heen@collabora.co.uk>
Mon, 12 Jul 2010 08:59:53 +0000 (10:59 +0200)
committerTollef Fog Heen <tfheen@err.no>
Thu, 31 Jan 2013 17:01:44 +0000 (18:01 +0100)
curiouscat is used to filter the output of a given command.  If it matches,
the full standard out and standard error are printed.

This is useful if you have scripts run from cron that intermittently
print out "No such file or directory" because the directory structure
was changed underneath their feet, but you want to capture any other
errors.

If you pass -v, it will print stdout/stderr if there are lines that do
not match the pattern(s).

curiouscat [new file with mode: 0755]

diff --git a/curiouscat b/curiouscat
new file mode 100755 (executable)
index 0000000..97c065c
--- /dev/null
@@ -0,0 +1,59 @@
+#!/usr/bin/perl
+
+=head1 NAME
+
+cgrep - grep the output of a command, only printing stdout/stderr if match
+
+=head1 SYNOPSIS
+
+cgrep [-v] PATTERN COMMAND...
+
+=head1 DESCRIPTION
+
+cgrep runs a command, buffering the output from both standard out and
+standard error, looking for a matching pattern.  If a matching pattern
+is found, stdout and stderr are printed and cgrep exits with the exit
+code of COMMAND.
+
+If the -v switch is passed, cgrep switches into reverse mode where it
+will print if there are any lines not matching PATTERN.
+
+=head1 AUTHOR
+
+Copyright 2010 by Collabora Limited, written by Tollef Fog Heen
+<tollef.fog.heen@collabora.co.uk>
+
+Licensed under the GNU GPL.
+
+=cut
+
+use warnings;
+use strict;
+use IPC::Run qw( start pump finish timeout );
+
+$|=1;
+
+my $reverse = 0;
+use Getopt::Long;
+GetOptions("v" => \$reverse) || die "usage: cgrep [-v] PATTERN COMMAND...\n";
+
+my $pattern = shift @ARGV;
+my @command = @ARGV;
+
+my ($in, $out, $err);
+my $h = IPC::Run::start \@command, \*STDIN, \$out, \$err;
+
+$h->finish;
+
+if ($reverse) {
+       if ($out !~ /$pattern/m and $err !~ /$pattern/m) {
+               print STDOUT $out;
+               print STDERR $err;
+       }
+} else {
+       if ($out =~ /$pattern/m or $err =~ /$pattern/m) {
+               print STDOUT $out;
+               print STDERR $err;
+       }
+}
+exit $h->result or 0;