Wait on an arbitrary process containing a pattern

Skip Montanaro montnaro at sprite.steinmetz.ge.com
Wed Feb 10 22:42:25 AEST 1988


I would like to be able to wait on an arbitrary process, given a pattern
that occurs in its command string. For instance, I have a peripheral cleanup
task in a Makefile that compresses and archives some intermediate files. I
don't want the mainline build to be slowed down by this peripheral work, but
at the same time, the separate archiving commands all write to the same
archive file, so they have to wait for each other. Here's roughly how the
Makefile looks:

target.o : target.for
	... some initial stuff that generates target.f
	(compress target.f ; \
		ar /tmp/arch/intermed.a target.f; \
		rm target.f.Z)&
	... compile target.f into target.o

Clearly, that middle step must wait until it can get clear access to the
archive file. So, not knowing the process id of the previous ar command, I'd
like to wait for it's completion:

target.o : target.for
	... some initial stuff that generates target.f
	(waiton "ar /tmp" ; \
		compress target.f ; \
		ar /tmp/arch/intermed.a target.f; \
		rm target.f.Z)&
	... compile target.f into target.o

I wrote a relatively straightforward version of waiton that discovered the
highest numbered process whose command line contained the indicated pattern:

------------------------------------------------------------------------------
#!/bin/sh
# wait for the last (highest numbered) process to complete that contains the
# string in argv[1]

if [ $# = 0 ] ; then
  echo "usage: $0 pattern"
  exit 1
fi

s=$1

# The following pipeline is intended to grab the last process with $s in its
# command line, excluding this process, and any grep processes.  It should
# catch the command which we are waiting on and any other waiton processes.
# Clearly, this won't work if you want to "waiton grep".  It is also not
# going to work when the process numbering wraps around to zero.  It tacitly
# assumes that the last process in the list is waiting on the next to the
# last process on the list, and so on.

j=`ps -a|grep "$s"|grep -v ";"|grep -v "^ *$$"|grep -v grep|sort -n|tail -1`

# pid, if it exists, into $1
set X $j
shift

if [ $# -gt 0 ] ; then
  wait $1
fi
------------------------------------------------------------------------------

In principal, this would work okay, except that the wait command will
apparently only wait for child processes, even if you are running as root.

My current hacked solution replaces the wait with a sleep, throws the whole
thing in a "while true" loop, and lengthens the sleep time on each pass
through the loop. Can somebody tell me whether or not I can get wait, or
some variant thereof, to wait on completion of an arbitrary process?

Thanks,

Skip (montanaro at ge-crd.arpa, uunet!steinmetz!sprite!montanaro)



More information about the Comp.unix.questions mailing list