how to convert shell captures into anyevent style?
Darin McBride
darin.mcbride at shaw.ca
Thu Mar 29 19:27:58 CEST 2012
On Thursday March 29 2012 6:48:09 PM Zsbán Ambrus wrote:
> On 3/29/12, Fulko Hew <fulko.hew at gmail.com> wrote:
> > foreach (`prog|prog|prog`) {
> >
> > What I obviously need to do is to turn my obtainer() into an event driven
> > aspect too! And I think what I want is an 'IO Watcher', but...
>
> Take a look at the run_cmd function in the AnyEvent::Util module. It
> spawns you a program (in this case you'll ask it spawn a shell so it
> interprets all those inner pipe to you) and handles reading its
> output. When it's finished, split the output to lines.
If you really want to go all the way with AE here, making it entirely
asynchronous, run_cmd is still the right way, but you can set some callbacks
for stdout and stderr such that you get the lines as they come in. I see
nothing in the docs that say, however, that you're guaranteed to get full
lines, though, in general, assuming short enough lines, that's what I've been
seeing in my own usage. That may, however, be an artefact of how my
subprograms produce their output (they may flush on line breaks, which is a
reasonable default for stderr).
Also, you are likely to get more than one line at a time, again, depending on
how the buffering works out.
I have code that accumulates the output into a separate buffer, splits that on
line breaks, sends it on to the code that is interested, but keeps partial
lines hidden away in the buffer for the next callback, so that the business-
logic code never sees a partial line, which greatly simplifies that code.
Personally, I've done the same thing with IO::Select and IPC::Open3.
AnyEvent::Util::run_cmd is FAR simpler to use, and to get right.
More information about the anyevent
mailing list