You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何实现Haskell程序惰性转发文本至Shell程序并惰性获取输出?

实现Haskell程序转发并处理外部进程的IO流

要实现将自身标准输入转发至外部进程(如grep)、并对外部进程的输出/错误流做后处理后输出的功能,可以借助Haskell的process库管理进程与管道,结合并发线程处理多IO流的持续流转。

依赖准备

确保项目依赖process包,在Cabal文件中添加:

build-depends: base >= 4.14 && < 5, process >= 1.6

完整代码示例

import System.Process
import System.IO
import Control.Concurrent (forkIO)
import Control.Monad (forever, void)

-- 输入预处理逻辑:可根据需求修改,示例为给每行加前缀
preprocessInput :: String -> String
preprocessInput = unlines . map ("[INPUT] " ++) . lines

-- 标准输出后处理逻辑:示例为给每行加前缀
postprocessOutput :: String -> String
postprocessOutput = unlines . map ("[OUTPUT] " ++) . lines

-- 标准错误后处理逻辑:示例为给每行加前缀
postprocessError :: String -> String
postprocessError = unlines . map ("[ERROR] " ++) . lines

main :: IO ()
main = do
    -- 配置外部进程(以grep匹配"pattern"为例),开启管道连接IO流
    let procConf = (proc "grep" ["pattern"])
            { std_in = CreatePipe
            , std_out = CreatePipe
            , std_err = CreatePipe
            }
    (Just procIn, Just procOut, Just procErr, procHandle) <- createProcess procConf

    -- 设置所有IO流为行缓冲,保证实时处理与输出
    mapM_ (`hSetBuffering` LineBuffering) [stdin, stdout, stderr, procIn, procOut, procErr]

    -- 启动线程:读取自身stdin,预处理后写入外部进程的stdin
    void $ forkIO $ forever $ do
        inputLine <- hGetLine stdin
        hPutStrLn procIn $ preprocessInput inputLine

    -- 启动线程:读取外部进程的stdout,后处理后输出到自身stdout
    void $ forkIO $ forever $ do
        outputLine <- hGetLine procOut
        hPutStrLn stdout $ postprocessOutput outputLine

    -- 启动线程:读取外部进程的stderr,后处理后输出到自身stderr
    void $ forkIO $ forever $ do
        errLine <- hGetLine procErr
        hPutStrLn stderr $ postprocessError errLine

    -- 等待外部进程终止,清理管道句柄
    waitForProcess procHandle
    mapM_ hClose [procIn, procOut, procErr]

关键细节说明

  • 管道配置:通过CreatePipe开启进程与自身的IO管道,实现数据双向流转。
  • 缓冲设置:行缓冲模式避免数据积压,确保输入输出能实时响应,适合持续处理场景。
  • 并发处理:用forkIO启动独立线程分别处理输入、输出、错误流,避免单线程阻塞导致IO停滞。
  • 自定义处理逻辑:修改preprocessInput、postprocessOutput、postprocessError函数即可实现任意预处理/后处理需求,比如字符串替换、内容过滤、格式转换等。

内容的提问来源于stack exchange,提问作者Enlico

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 18:56:17