如何在 Haskell 中组合句柄?
我希望在 Haskell 中有类似 bash 的 2>&1
重定向的功能,将进程中的 stdout
和 stderr
组合成一个 <代码>句柄。直接使用 System.Process.createProcess 或类似的库函数来完成此操作会很好,特别是如果它使用与来自句柄的 bash 重定向交错输入相同的语义。
createProcess 提供的灵活性一开始看起来很有希望:可以指定一个用于标准文件描述符的句柄,因此可以使用相同的句柄为 stdout
和 stderr
提供。但是,Handle
参数必须在调用之前已存在。如果无法在调用函数之前凭空创建一个句柄,我不确定问题是否可以通过这种方式解决。
编辑:该解决方案需要在任何平台上都能工作。
I'd like to have something like bash's 2>&1
redirect in Haskell that combines stdout
and stderr
from a process into a single Handle
. It would be nice to do this directly with System.Process.createProcess
or a similar library function, particularly if it used the same semantics as the bash redirect w.r.t. interleaving input from the handles.
The flexibility offered by createProcess
seems promising at first: one can specify a Handle
to use for the standard file descriptors, so the same Handle
could be given for both stdout
and stderr
. However, the Handle
arguments must already exist before the call. Without the ability to create a Handle
from thin air before calling the function, I'm not sure the problem can be solved this way.
Edit: The solution needs to work regardless of platform.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
来自此处:
From here:
掌握
Handle
并不难:System.IO
提供常量stdin、stdout、stderr :: Handle
和函数>withFile::FilePath -> IO模式-> (句柄->IO r)-> IO r
和openFile::FilePath -> IO模式-> IO 句柄。
或者,您可以从
createProcess
请求新管道,并将自己设置为转发服务(从您孩子的新stdout
和stderr
句柄读取并将两者发送到您喜欢的任何地方)。Getting your hands on a
Handle
isn't too hard:System.IO
offers constantsstdin,stdout,stderr :: Handle
and functionswithFile :: FilePath -> IOMode -> (Handle -> IO r) -> IO r
andopenFile :: FilePath -> IOMode -> IO Handle
.Alternately, you could request new pipes from
createProcess
and set yourself up as a forwarding service (reading from the newstdout
andstderr
handles of your child and sending both to wherever you like).由于 Windows 支持
管道 (3)< /code>
原生和 GHC 的 IO 库 在 Windows 内部使用 CRT 文件描述符,因此有可能提出一个至少在 Windows 和 *nix 上都有效的解决方案。基本算法是:
pipe
。这为您提供了两个文件描述符,您可以使用fdToHandle'
。createProcess
,并将stdout
和stderr
均设置为管道的写入端。System.Posix.Internals
导出c_pipe
的 模块默认是隐藏的,但您可以编译一个自定义版本的base
来访问它(提示:使用 cabal-dev)。或者,您可以通过 FFI 访问pipe
。 注意:此解决方案是 GHC 特定的。Since Windows supports
pipe (3)
natively and GHC's IO library uses CRT file descriptors internally on Windows, it is possible to come up with a solution that works on both Windows and *nix at least. The basic algorithm is:pipe
. This gives you two file descriptors which you can convert toHandles
withfdToHandle'
.createProcess
withstdout
andstderr
both set to the pipe's write end.The
System.Posix.Internals
module, which exportsc_pipe
, is hidden by default, but you can compile a custom version ofbase
that lets you access it (tip: use cabal-dev). Alternatively, you can accesspipe
via FFI. NB: this solution is GHC-specific.