Существует ли канал Haskell, который может выполнять процесс и захватывать его потоки stderr
и stdout
(отдельно)? Возможность передать stdin
в процесс была бы идеальной, поскольку канал тоже был бы идеальным, но не требованием (для этого я могу использовать файл).
Haskell Conduit из процесса захвата как stdout, так и stderr
Ответы (1)
Вот пример из статьи школы Haskell Данные .Conduit.Process:
{-# LANGUAGE OverloadedStrings #-}
import Control.Applicative ((*>))
import Control.Concurrent.Async (Concurrently (..))
import Data.Conduit (await, yield, ($$), (=$))
import qualified Data.Conduit.Binary as CB
import qualified Data.Conduit.List as CL
import Data.Conduit.Process (ClosedStream (..), streamingProcess,
proc, waitForStreamingProcess)
import System.IO (stdin)
main :: IO ()
main = do
putStrLn "Enter lines of data. I'll run ./base64-perl on it."
putStrLn "Enter \"quit\" to exit."
((toProcess, close), fromProcess, fromStderr, cph) <-
streamingProcess (proc "./base64-perl" [])
let input = CB.sourceHandle stdin
$$ CB.lines
=$ inputLoop
=$ toProcess
inputLoop = do
mbs <- await
case mbs of
Nothing -> close
Just "quit" -> close
Just bs -> do
yield bs
inputLoop
output = fromProcess $$ CL.mapM_
(\bs -> putStrLn $ "from process: " ++ show bs)
errout = fromStderr $$ CL.mapM_
(\bs -> putStrLn $ "from stderr: " ++ show bs)
ec <- runConcurrently $
Concurrently input *>
Concurrently output *>
Concurrently errout *>
Concurrently (waitForStreamingProcess cph)
putStrLn $ "Process exit code: " ++ show ec
В основном это пример в статье с добавленным потоком для обработки stderr.
Он вызывает эту программу Perl, которая выводит вывод как на стандартный вывод, так и на стандартный вывод:
#!/usr/bin/env perl
use strict;
use warnings;
use MIME::Base64;
$| = 1;
my $timeout = 3;
my $buf = "";
while (1) {
my $rin = '';
vec($rin, fileno(STDIN), 1) = 1;
my ($nfound) = select($rin, undef, undef, $timeout);
if ($nfound) {
my $nread = sysread(STDIN, $buf, 4096, length($buf));
last if $nread <= 0;
print encode_base64($buf);
$buf = "";
} else {
print STDERR "this is from stderr\n";
}
}
person
ErikR
schedule
11.11.2015