haskell 中的 IO 句柄的多行内容不显示任何内容

multiline contents of a IO handle in haskell display nothing

我一直在试验 Haskell。我正在尝试编写一个网络爬虫,我需要使用外部 curl 二进制文件(由于某些代理设置,curl 需要一些特殊的参数,这些参数似乎是 impossible/hard 以在 haskell 代码中设置,所以我宁愿将它作为命令行选项传递。但那是另一回事...)

在底部的代码中,如果我用 curl 而不是 curl --help 更改标记的行,输出将正确呈现并给出:

"curl: try 'curl --help' or 'curl --manual' for more information
" 

否则字符串为空 - 因为“curl --help”响应是多行的。 我怀疑在 haskell 中,每一行都会清除缓冲区。 (同样适用于其他简单的 shell 命令,例如 lsls -l 等)

我该如何解决?

代码:

import System.Process
import System.IO
main = do
    let sp = (proc "curl --help"[]){std_out=CreatePipe} -- *** THIS LINE ***
    (_,Just out_h,_,_)<- createProcess sp
    out <-hGetContents out_h
    print out

如果您想将参数传递给 curl,您必须在列表中传递它:

sp = (proc "/usr/bin/curl" ["--help"]) {std_out=CreatePipe}

然后你会得到整个字符串的完整输出。

proc 将可执行文件的名称作为第一个参数,而不是 shell 命令。也就是说,当您使用 proc "foo bar" 时,您指的不是 foo 可执行文件,而是确切命名为 foo bar 的可执行文件,其文件名中包含 space。

这在实践中是一个有用的功能,因为有时你确实有spaces(例如在Windows你可能有c:\Program Files\Foo\Foo.exe).使用 shell 命令,您必须在命令字符串中转义 spaces。更糟糕的是,还需要转义其他一些字符,而且检查这些字符到底是什么很麻烦。 proc 通过根本不使用 shell 而是将字符串原样传递给 OS.

来回避问题

对于可执行参数,proc 采用单独的参数列表。例如

proc "c:\Program Files\Foo\Foo.exe" ["hello world!%$"]

请注意,参数也不需要转义。