I was working a few month(year? wow yes years) on some Sun Solaris 8 box. And I remenber That SunOs include a handy command which is pswait.

I used this quite a lot, specialy when working remotely over slow link to wait for the end of downloads for example. While on linux I was using a simple loop like
while [ -d /proc/$1 ];do sleep 1;done 
(handy /proc filesystem ) for replacing pswait, I was stuck whith specific shell scripts involving /bin/ps and grep on other platform like darwin or cygwin ... or whatever.

so when I discovered recently Proc::ProcessTable (thanks rob_au )I decided to write my multi-platform pswait, so now I can use the same command everywhere

#!/usr/bin/perl use strict; use Proc::ProcessTable; exit if ( $#ARGV == -1 ); $|++; my $ptable = new Proc::ProcessTable; my %waited = (); my %proc; $proc{ $_->pid }=$_->fname foreach (@{$ptable->table}); use Getopt::Long; GetOptions( 'e|exit+' => \( my $endfirst = 0 ), 's|sleep=i' => \( my $sleeptime = 1 ), 'v|verbose+' => \( my $verbose = 0), 'h|help' => sub { print "usage: $0 [proces ID|name][...]\n" . "\t-s x --sleep x second(S) to sleep between checks\n" . "\t-e --exit exit on first terminated process\n" . "\t-v --verbose verbose mode\n" . "\t-h --help this help\n"; exit; }); foreach (@ARGV) { next if ( $_ == $$ ); # DON'T wait for myself ! if (/\d+/) { if ( exists $proc{$_} ) { $waited{$_}++; } else { print "nothing like $_\n" if $verbose } next; } foreach my $p ( keys %proc ) { next if ( $p == $$ ); # DON'T wait for myself I said ! $waited{$p}++ if ( $proc{$p} =~ /$_/ ); } } if ($verbose) { print "I am process $$\n"; print "waiting after $_ \n" for ( keys %waited ); print "sleep time set to $sleeptime s\n"; print "will exit on first terminated process\n" if ( $endfirst ); } my $count = scalar keys(%waited); while ( scalar keys(%waited) ) { sleep $sleeptime; %proc = (); $proc{ $_->pid }++ foreach (@{$ptable->table}); foreach my $p ( keys %waited ) { if ( !exists $proc{$p} ) { print "gone $p\n" if $verbose; delete $waited{$p}; } } last if (( scalar keys(%waited) < $count ) && ($endfirst)); } __END__ =head1 PSWAIT pswait - waiting for process(es) to end before doing things =head1 SYNOPSIS pswait [options] [process ID|NAME ...] Options: -h --help brief help message -v --verbose be verbose -e --exit exit after first process end -s x --sleep x set sleep time to x second (default to 1) =head1 OPTIONS =over 8 =item B<-e, --exit> When giving a list of process to watch, exit when the first process en +d, it is usefull to easily manage a pool of proces with a shell scrip +t. =item B<-h. --help> Print a brief help message and exits. =item B<-s x, --sleep x> set sleep time to x seconds between process checking, default to 1 sec +ond. On small machines (or overloaded machines) it could help to chec +k process state only once every minutes instead, using for example -s + 60 =item B<-v, --verbose> Inform you on what happening ... which process ends, which process ID +are watched for state (usefull when using process names on command li +ne). =back =head1 DESCRIPTION B<pswait> will read the process table of the system and wait for some process to end =head1 AUTHOR DominiX <dominix@despammed.com> =cut

So as usual, I'll be waiting for your advised recommandations for security, improvement best practice ... and so on, thanks in advance
It looks like there is problem compiling Proc::ProcessTable on Mac Os X . have a look here if interested.
Update 1: more explicit variable name suggested by rob_au
Update 2: use of Getopt::Long and pod formatting as suggested by rob_au and others
--
dominix

Replies are listed 'Best First'.
Re: PleaSe WAIT for the process to end.
by BUU (Prior) on Jan 05, 2004 at 09:59 UTC
    I'm a tad confused, what exactly does this (and pswait) do? Isn't the normal practice to wait untill an operation finishes and then return?
      exuse me, I didn't mention it as that was obvious to me with such a name.

      what pswait does : it waits for some [usualy backgrounded] process to end before quiting. So for example you can wait for a specific [backgrounded] wget/ncftp downloads to finish or for a bunch of similar process to terminate before launching another command:

      pswait httpd; backup.sh
      
      here backup.sh will be launched after all httpd deamons exited.
      pswait 10123; mail -s "picture processing terminated" me@home
      
      if you want an email alerting that your job 10123 is done
      This command is very usefull when working over slow networks links like dial up modems or when you have small number of process allowed on a system.
      Update: just added pod documentation.
      --
      dominix
        if (/--*sl*e*e*p*=(\d+)/i) { $sleeptime = $1; next } if (/--*ex*i*t*/i) { $endfirst = 1; next } if (/--*ve*r*b*o*s*e*/i) { $verbose = 1; next } if (/--*he*l*p*/i) {

        This is some really cool typo checking!


        --sleeeeeeeeeee
        --sleeeee
        --slp
        --sp

        Useful for intoxicated Unix users everywhere!

Re: PleaSe WAIT for the process to end.
by Anonymous Monk on Feb 13, 2004 at 23:02 UTC
    Will this help is eliminating zombie processes or defunct processes? I use a perl script that retrieves several webpages and it is called every minute as a cron job. Occasional zombie processes result causing the cron job to skip a minute as the process hasn't been removed. 1. would this help in controlling the number of zombie processes? 2. Could this script be modified for use by another script? Jim
      in this state, this script doesn't interact with processes. It just monitor them and inform you when something append.
      So 1. you can use this script to monitor your process stream, and wait for less zombie to continue, but that may not be what you want. I think your problem is somewhere else, related to wait or fork you should better rewrite tune your script to keep a clean control over it. Or at least detach from cron.
      Did you check possible process number/resource/ulimit limitation ?
      NB: look for zombie in Super search, it will help.
      NB: subscribe to perlmonks, so you can have a message when someone reply to you.
      --
      dominix