zsh-users
 help / color / mirror / code / Atom feed
From: Bart Schaefer <schaefer@brasslantern.com>
To: zsh-users@sunsite.dk
Subject: Re: Scripting subprocesses and timed waits.
Date: Wed, 12 Jan 2005 17:49:40 +0000	[thread overview]
Message-ID: <1050112174941.ZM30863@candle.brasslantern.com> (raw)
In-Reply-To: <20050112095614.A16221@redfish.gatech.edu>

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".


      reply	other threads:[~2005-01-12 17:51 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2005-01-12 14:56 Jason Price
2005-01-12 17:49 ` Bart Schaefer [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1050112174941.ZM30863@candle.brasslantern.com \
    --to=schaefer@brasslantern.com \
    --cc=zsh-users@sunsite.dk \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://git.vuxu.org/mirror/zsh/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).