From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 6349 invoked from network); 12 Jan 2005 17:51:44 -0000 Received: from news.dotsrc.org (HELO a.mx.sunsite.dk) (130.225.247.88) by ns1.primenet.com.au with SMTP; 12 Jan 2005 17:51:44 -0000 Received: (qmail 27084 invoked from network); 12 Jan 2005 17:51:39 -0000 Received: from sunsite.dk (130.225.247.90) by a.mx.sunsite.dk with SMTP; 12 Jan 2005 17:51:39 -0000 Received: (qmail 13852 invoked by alias); 12 Jan 2005 17:50:48 -0000 Mailing-List: contact zsh-users-help@sunsite.dk; run by ezmlm Precedence: bulk X-No-Archive: yes X-Seq: 8362 Received: (qmail 13842 invoked from network); 12 Jan 2005 17:50:47 -0000 Received: from unknown (HELO a.mx.sunsite.dk) (130.225.247.88) by sunsite.dk with SMTP; 12 Jan 2005 17:50:47 -0000 Received: (qmail 25668 invoked from network); 12 Jan 2005 17:49:48 -0000 Received: from out005pub.verizon.net (HELO out005.verizon.net) (206.46.170.143) by a.mx.sunsite.dk with SMTP; 12 Jan 2005 17:49:44 -0000 Received: from candle.brasslantern.com ([4.11.10.129]) by out005.verizon.net (InterMail vM.5.01.06.06 201-253-122-130-106-20030910) with ESMTP id <20050112174943.MEBQ28362.out005.verizon.net@candle.brasslantern.com> for ; Wed, 12 Jan 2005 11:49:43 -0600 Received: from candle.brasslantern.com (IDENT:schaefer@localhost [127.0.0.1]) by candle.brasslantern.com (8.12.11/8.12.11) with ESMTP id j0CHnfBk030865 for ; Wed, 12 Jan 2005 09:49:41 -0800 Received: (from schaefer@localhost) by candle.brasslantern.com (8.12.11/8.12.11/Submit) id j0CHnfIC030864 for zsh-users@sunsite.dk; Wed, 12 Jan 2005 09:49:41 -0800 From: Bart Schaefer Message-Id: <1050112174941.ZM30863@candle.brasslantern.com> Date: Wed, 12 Jan 2005 17:49:40 +0000 In-Reply-To: <20050112095614.A16221@redfish.gatech.edu> Comments: In reply to Jason Price "Scripting subprocesses and timed waits." (Jan 12, 9:56am) References: <20050112095614.A16221@redfish.gatech.edu> X-Mailer: Z-Mail (5.0.0 30July97) To: zsh-users@sunsite.dk Subject: Re: Scripting subprocesses and timed waits. MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-Authentication-Info: Submitted using SMTP AUTH at out005.verizon.net from [4.11.10.129] at Wed, 12 Jan 2005 11:49:42 -0600 X-Spam-Checker-Version: SpamAssassin 2.63 on a.mx.sunsite.dk X-Spam-Level: * X-Spam-Status: No, hits=1.6 required=6.0 tests=RCVD_IN_NJABL,RCVD_IN_SORBS autolearn=no version=2.63 X-Spam-Hits: 1.6 On Jan 12, 9:56am, Jason Price wrote: } Subject: Scripting subprocesses and timed waits. } } I'd like to find a way to fire off several of these, and notice when } each finishes. [...] } Ideally I'd like to fire off each of these scripts into the background, } if they all finish quickly, move on. If one or more take more than the } full time I give them, kill them. } } Is there a clever zsh way to do this? I've noticed coprocesses in the } past and in the manual, but I haven't figured out how to control it } sufficiently for this usage. This would be easier to do "right" in any number of other languages that give you more direct access to the system calls for process control. However, you can hack up something that mostly gets it done by using the zsh/parameter module and an extra process. Something like: timed_wait() { zmodload -i zsh/parameter || return 1 local job { # Start a job to interrupt the parent after a delay. # First parameter of this function is the delay time. # Disown it so "wait" won't block on it. { sleep $1 ; kill -INT $$ } &! # Remember its PID so we can kill it once not needed. job=$! # Wait for all jobs matching the second parameter. # Waits for all jobs if there is no second parameter. # Redirect stderr in case a race means any job has # exited before this gets around to waiting for it. wait %${(k)^jobtexts[(R)$2*]} 2>/dev/null # Kill the killer before it kills us. kill $job } always { # Kill any running jobs matching the second parameter. # Kills all jobs if there is no second parameter. # Redirect stderr in case a race means any job has # exited before this gets around to killing it. kill %${(k)^jobtexts[(R)$2*]} 2>/dev/null } } E.g., for x in {1..9}; do sleep $[x*3] & done timed_wait 20 sleep You may need to fool around with signal traps and with what signal is sent by the disowned job if this is used in a context where the parent shell can't be allowed to receive an interrupt. And if you don't have zsh 4.2, you'll have to use an EXIT trap rather than "always".