【问题标题】:Can I make readProcess drop the quotes?我可以让 readProcess 去掉引号吗?
【发布时间】:2013-11-11 07:44:18
【问题描述】:

我正在尝试编写一些在外部运行grep 的代码,然后分析输出。具体来说,我想做

grep <username> *.test

但是,很遗憾,

readProcess "grep" [username, "*.test"]

似乎在参数周围用双引号生成命令

grep "<username>" "*.test"

并且由于没有名为星号点测试的单独文件,grep barfs。有带有.test 扩展名的文件。

我可以说服readProcess(或类似的东西)发出我想要的命令吗?

【问题讨论】:

    标签: haskell process io system


    【解决方案1】:

    "*" 不是由grep 扩展的,而是由shell 扩展的。如果你想要扩展,你应该运行类似sh -c 'grep username *.test 的东西。

    更好的方法是使用 createProcessShellCommand 参数。

    【讨论】:

    • System.Process 没有与readProcess 等效的外壳转义功能,这有点不方便。这是一个很常见的用例。
    • 这是一个有用的线索,谢谢。我的解决方法,现在按预期完成工作,是在 shell 脚本中编写 grep 命令,然后使用 readProcessWithExitCode 调用脚本,因为空响应是完全可以接受的,但 grep 报告为失败。
    【解决方案2】:

    你可能最好去createProcess,这是最通用的进程创建函数。比如……

    import System.Process
    import System.IO
    
    makeGrep username file = "grep " ++ username ++ " " ++ file
    
    main :: IO ()
    main = do
      (_, Just hOut, _, hProc) <- createProcess (
                                    (shell (makeGrep "bob" "*.test"))
                                    { std_out = CreatePipe }
                                  )
      exitCode <- waitForProcess hProc
      output <- hGetContents hOut
      print output
    

    【讨论】:

    • 这里要小心。您可能会被正在发生的惰性 I/O 严重咬伤。如果您查看System.ProcessreadProcess 的代码,您可以很好地了解安全执行此操作所需的内容。
    【解决方案3】:

    我通常使用来自System.Cmdsystem。您应该构建一个正确的 Shell 命令(例如,进行所有转义),但它具有使用提供的字符串的优点。

    【讨论】:

    • 我不确定我是如何抓取以这种方式发出的命令的输出的。
    • 嗯,我错过了这个要求。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-06-13
    • 2023-03-06
    • 2020-11-01
    • 1970-01-01
    • 2014-04-07
    • 2019-04-23
    • 2023-03-14
    相关资源
    最近更新 更多