Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

Re: Scripting subprocesses and timed waits.



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



Messages sorted by: Reverse Date, Date, Thread, Author