【问题标题】:Binding the result of a system command to a variable in Haskell将系统命令的结果绑定到 Haskell 中的变量
【发布时间】:2016-05-09 04:53:36
【问题描述】:

如何在 Haskell 中运行系统命令将其结果(即标准输出)绑定到变量?在 pseudo-haskell 中,我正在寻找类似以下的内容:

import System.Process

main = do output <- callCommand "echo hi"
          putStrLn output -- result: "hi"

这不起作用。有没有类似的东西?

【问题讨论】:

标签: haskell system


【解决方案1】:

这是一些工作代码:

import System.Process

main :: IO ()
main = do
  let stdin' = ""
  (errCode, stdout', stderr') <- readProcessWithExitCode "echo" ["hi"] stdin'
  putStrLn $ "stdout: " ++ stdout'
  putStrLn $ "stderr: " ++ stderr'
  putStrLn $ "errCode: " ++ show errCode

正如 Carsten 所说,您可以使用 readProcess,但我更喜欢这个版本,因为任何严重的使用,您很快就会对为什么您的命令会静默失败感到非常困惑(如果您在命令行中运行,stdout 和 stderr是,当然,显示)。

【讨论】:

  • 备注:如果您想在相同的上下文中使用System.IO,请不要使用名称stdoutstderrstdin,因为System.IO 将这些名称导出为@987654329 @ 到标准流。
  • @jamshidh:我在另一篇文章中对这个答案提出了后续问题:stackoverflow.com/questions/37197388/…
  • @jamshidh 你知道吗why this command fails?
【解决方案2】:

扩展 jamshidh 的答案,如果您不想将 stdout 和 stderr 设置为 String,而希望将它们设置为 ByteStringText,则可以使用 process-extras 包。

你也可以使用我的process-streaming 包:

$ import System.Process.Streaming
$ execute (piped (shell "echo foo")) (liftA3 (,,) (foldOut intoLazyBytes)    
                                                  (foldErr intoLazyBytes)
                                                  exitCode)
("foo\n","",ExitSuccess)

也适用于Text

$ import System.Process.Streaming.Text
$ execute (piped (shell "echo foo")) (liftA3 (,,) (foldOut (transduce1 utf8x intoLazyText)) 
                                                  (foldErr (transduce1 utf8x intoLazyText)) 
                                                  exitCode)
("foo\n","",ExitSuccess)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-04-20
    • 2013-01-12
    • 1970-01-01
    • 2012-06-21
    • 1970-01-01
    • 1970-01-01
    • 2016-03-11
    相关资源
    最近更新 更多