Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I run a command in a loop until I see some string in stdout?

Tags:

linux

bash

shell

I'm sure there's some trivial one-liner with perl, ruby, bash whatever that would let me run a command in a loop until I observe some string in stdout, then stop. Ideally, I'd like to capture stdout as well, but if it's going to console, that might be enough.

The particular environment in question at the moment is RedHat Linux but need same thing on Mac sometimes too. So something, generic and *nixy would be best. Don't care about Windows - presumably a *nixy thing would work under cygwin.

UPDATE: Note that by "observe some string" I mean "stdout contains some string" not "stdout IS some string".

like image 373
Alex Miller Avatar asked Sep 24 '08 18:09

Alex Miller


2 Answers

In Perl:

#!/usr/local/bin/perl -w

if (@ARGV != 2)
{
    print "Usage: watchit.pl <cmd> <str>\n";
    exit(1);
}

$cmd = $ARGV[0];
$str = $ARGV[1];

while (1)
{
    my $output = `$cmd`;
    print $output; # or dump to file if desired
    if ($output =~ /$str/)
    {
        exit(0);
    }
}

Example:

[bash$] ./watchit.pl ls stop
watchit.pl
watchit.pl~
watchit.pl
watchit.pl~
... # from another terminal type "touch stop"
stop 
watchit.pl
watchit.pl~

You might want to add a sleep in there, though.

like image 148
Derek Park Avatar answered Sep 19 '22 14:09

Derek Park


There's a bunch of ways to do this, the first that came to mind was:

OUTPUT=""; 
while [ `echo $OUTPUT | grep -c somestring` = 0 ]; do 
  OUTPUT=`$cmd`; 
done

Where $cmd is your command to execute.

For the heck of it, here's a BASH function version, so you can call this more easily if it's something you're wanting to invoke from an interactive shell on a regular basis:

function run_until () {
  OUTPUT="";
  while [ `echo $OUTPUT | grep -c $2` = 0 ]; do
    OUTPUT=`$1`;
    echo $OUTPUT;
  done
}

Disclaimer: only lightly tested, may need to do some additional escaping etc. if your commands have lots of arguments or the string contains special chars.

EDIT: Based on feedback from Adam's comment - if you don't need the output for any reason (i.e. don't want to display the output), then you can use this shorter version, with less usage of backticks and therefore less overhead:

OUTPUT=0; 
while [ "$OUTPUT" = 0 ]; do 
  OUTPUT=`$cmd | grep -c somestring`;
done

BASH function version also:

function run_until () {
  OUTPUT=0; 
  while [ "$OUTPUT" = 0 ]; do 
    OUTPUT=`$1 | grep -c $2`; 
  done
}
like image 43
Jay Avatar answered Sep 21 '22 14:09

Jay