amphp / process

An async process dispatcher for Amp.
MIT License
233 stars 30 forks source link

Catching STDERR output #66

Open jigarius opened 1 year ago

jigarius commented 1 year ago

I'm not sure if y'all take support requests directly through the issue queue, so I'll try my luck. I created the tool Drall and one of it's main features is parallel processing, which is powered by amphp/process.

Reference: context.

Question 1: Catch STDERR

$sOutput = yield ByteStream\buffer($process->getStdout());

Here, I only get the STDOUT contents from $process. How do I get both STDOUT and STDERR, preferably, intermingled output, i.e. not in separate variables. Is appending 2>&1 the only way? Or is there another way?

Question 2: No buffer

Currently, I use ByteStream\buffer($process->getStdout()); where I catch the output in a variable. Is there a way to let the output go to STDOUT directly instead of catching it in a variable?

Any help will be appreciated.

kelunik commented 1 year ago

You can use Amp\ByteStream\pipe to stream the contents of one stream to another stream. Doing this for both stdout and stderr will likely give you what you're asking for:

async(ByteStream\pipe(...), $process->getStdout(), ByteStream\getStdout())->ignore();
async(ByteStream\pipe(...), $process->getStderr(), ByteStream\getStderr())->ignore();
kelunik commented 1 year ago

If you want both streamed to stdout, you can of course change the destination in the second call.

jigarius commented 1 year ago

Thanks a ton for the answer. One last question in this regard.

In the given context, how do I break the each?

Loop::run(function () use ($values, $command, $placeholder, $output, $progressBar, $workers, &$exitCode) {
  yield ConcurrentIterator\each(
    Iterator\fromIterable($values),
    new LocalSemaphore($workers),
    function ($value) use ($command, $placeholder, $output, $progressBar, &$exitCode) {
      // TODO: Break the "each".
    }
}

Will it be a Loop::stop(); by any chance?