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

# Call as  mpid string1 string2 ... /regexp1/ /regexp2/ ...
# Prints the PIDs of all processes whose `comm' contains one of the
# strings, or matches one of the regexps.  As such, it is a more
# flexible version of pidof.
#
# Assumes a Unix system with SysV-style ps(1), supporting the -o
# argument and the `comm' field.  Tested on Linux (procps 2.0.0) and 
# Solaris 7.

use strict;

# Call as:  any { predicate } @list
# Returns true if the predicate returns true for any element of the list.
# The predicate is called as a function of one argument---this is different
# from the norm for perl operators, where the predicate would be called with
# $_ bound to the list element.  Note that modifying $_[0] in the predicate
# code will modify the elements of the list.
sub any(&@) {
	my $pred = shift;
	foreach my $x (@_) {
		my $y = $pred->($x);
		return $y if $y;
	}
	return 0;
}

# If passed a string of the form "/regexp/", returns the same string
# with the // removed.  If passed a string of any other form, returns
# the string with regexp metacharacters quoted.
sub refix($) {
	local $_ = shift;
	return $1 if m,^/(.*)/$,;
	return quotemeta($_);
}

open(F,"ps -e -o pid,comm|");

print join " ",
 map { $_->[0] }
  grep { any { my $x=refix shift; $_->[1] =~ /$x/ } @ARGV }
   grep { defined $_->[0] and defined $_->[1] }
    map { [/^\s*([0-9]+)\s+(.*)/] }
     map { (/(.*)\n$/)[0] }
      <F>;
print "\n";
close F;
__END__
