gpt4 book ai didi

purescript - 如何在纯脚本中捕获子进程的输出?

转载 作者:行者123 更新时间:2023-12-04 01:56:03 26 4
gpt4 key购买 nike

我对 purescript 和 haskell(甚至 javascript 和 node)都是新手,所以我很难弄清楚如何在 purescript 中保存子进程的输出。我正在使用 purescript-node-childprocess 和 purescript-node-fs 模块。基本上,我遇到的问题是:

import Node.ChildProcess (CHILD_PROCESS, SpawnOptions, defaultSpawnOptions, Exit(..), spawn, onExit, stdout)
import Node.Stream (onData)

type CPEffect = forall e
. Eff (cp :: CHILD_PROCESS
, console :: CONSOLE
, err :: EXCEPTION
, buffer :: BUFFER | e
) Unit

-- | Basically a wrapper around the spawn command.
-- | Takes a command, an array of arguments, and a record of
-- | options to pass to spawn.
launch :: String -> Array String -> SpawnOptions -> CPEffect
launch cmd args opts = do
cmd' <- spawn cmd args opts
onExit cmd' defaultExitHdlr
-- My problem is with onData due to its return type
onData (stdout cmd') -- what do I put as the callback handler arg?
log $ "done with " <> cmd

如我上面的评论所示,问题出在来自 Node.Stream 模块的 onData 函数。问题出在第二个参数和返回类型中:

onData :: forall w eff
. Readable w (err :: EXCEPTION | eff)
-> (Buffer -> Eff (err :: EXCEPTION | eff) Unit)
-> Eff (err :: EXCEPTION | eff) Unit

由于返回的是返回 Unit 的 Eff,我该如何保存子进程的输出?第二个参数是一个函数,它接受一个 Buffer 并返回相同的类型。实际上,正是这个函数从 Readable(这是子进程的标准输出)获取数据。换句话说,第一个参数是来自子进程节点的标准输出流,第二个参数是一个回调处理程序,它将从标准输出流填充缓冲区。

但是由于回调处理程序返回 Unit,我不知道如何累积子进程的输出。我仍在学习 Monad 变形金刚,这是一个解决方案吗?我可以创建一个以某种方式包装它的 Writer monad 吗?

最佳答案

如果我打算在不使用 FFI 的情况下在纯脚本中执行此操作,我会使用 Ref,并在 onData 回调中读取 ref 值,通过将新数据附加到 ref 值来创建一个新字符串,然后用这个新字符串更新 ref 值。

WriterT 确实对这种事情很有用,虽然我可能不会在这种特殊情况下使用它,因为弄清楚如何让类型排列起来可能有点尴尬,因为回调需要 Eff,而不是WriterT something Eff.

我用来解决 Pulp 中这个确切问题的另一个选项是使用 npm 包 concat-stream。事实上,您可能会发现 Pulp 作为使用这些库的真实示例很有用 - 我认为模块 Pulp.Exec 和 Pulp.System.Stream 是您会感兴趣的。

关于purescript - 如何在纯脚本中捕获子进程的输出?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41445229/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com