如何在xmonad键绑定中使用readProcess的输出?

时间:2016-05-11 22:13:22

标签: haskell xmonad

好的,所以前段时间我正在考虑根据我框中脚本的输出来确定我的xmonad中键绑定的效果。我最终决定不这样做是出于无关的原因,但我最近尝试做类似的事情,就像学习Haskell一样。

所以,鉴于功能:

test = readProcess "echo" ["-n", "gvim"] []

这会抛出,因为测试返回IO String,而spawn需要一个String。

((modm, xK_y), spawn ("xmessage " ++ test))

确定。太酷了。我知道IO操作是不可预测的,所以它们应该分开。精细。所以我在网上做了一些讨论并得到了这个(删除了xmessage并且只想通过测试的输出):

((modm, xK_y), liftIO test >>= spawn)

这更糟糕。它烦人地编译但是当我尝试绑定时没有任何反应。 (我也只用spawn" xmessage test&#34取而代之;这很有效)

所以,那时我想"也许我的功能出了问题"所以我重申它,但是从GCHi我得到" gvim"哪个是对的。那么我把它写入haskell文件:

main = test >>= putStrLn
test = readProcess "echo" ["-n", "gvim"] []

也正常工作。

那么,我哪里出错了?

编辑:解决方案是使用runProcessWithInput而不是readProcess。 相关链接:https://ghc.haskell.org/trac/ghc/ticket/5212 xmonad io binding not working

1 个答案:

答案 0 :(得分:1)

<强>更新

显然,解决方案(请参阅下面的评论)是使用readProcessWithInput

原始答案

你这么说:

liftIO test >>= spawn

没有用,但是怎么样:

liftIO test >>= (\m -> spawn ("xmessage " ++ m))

另请注意,readProcess返回的字符串可能会在结尾处有换行符,这可能会影响事情。

还有一些事情需要尝试:

return "gvim" >>= (\m -> spawn ("xmessage " ++ m))


import Data.Char

do { m <- liftIO test;  spawn ("xmessage " ++ (filter isAlpha m)) }

第一个应该成功,因为它等同于spawn "xmessage grim"。第二个将从test的输出中删除任何换行符(实际上是任何非字母)。

可能会对正在发生的事情有所了解的其他一些事情:

  1. 使用以下内容创建名为/tmp/report的脚本:

    #!/bin/sh
    ( date; echo "/tmp/report was called with args" "$@") >> /tmp/output
    
  2. 使/tmp/report可执行。

  3. 运行/tmp/report并验证是否有两行附加到/tmp/output
  4. 在您的monad配置中,执行操作spawn "/tmp/report A"。通过查看预期的行是否附加到/tmp/output来测试操作。
  5. 尝试执行monad操作:

    liftIO (readProcess "/tmp/report" ["B"] "") >> spawn "/tmp/report A"
    

    (注意我们在这里使用的是>>,而不是>>=。)当您触发操作时,您应该会看到B调用的报告行以及{{1}的报告行调用。

  6. 根据您在文件A中看到的内容,您应该能够确定/tmp/output命令是否正在执行以及readProcess命令是否正在触发。