好的,前一段时间我想在我的xmonad中基于脚本的输出在我的xmonad中建立一个键绑定的效果。出于无关的原因,我最终决定不这样做,但最近我确实尝试做了一些类似的事情,只是作为学习Haskell的一个练习。
因此,给定以下函数:
test = readProcess "echo" ["-n", "gvim"] []这是因为test返回IO字符串,而spawn需要一个字符串。
((modm, xK_y), spawn ("xmessage " ++ test))好的。这很酷。我知道IO操作是不可预测的,因此应该将它们分开。很好。所以我在网上做了一些探索,得到了这个(省略了xmessage,只想自己传递test的输出):
((modm, xK_y), liftIO test >>= spawn)这更糟。它进行了令人讨厌的编译,但当我尝试绑定时什么也没有发生。(我还将其替换为"xmessage test“,这很有效)
所以,然后我想“也许我的函数有问题”,所以我重新编写了它,但从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
发布于 2016-05-12 06:39:09
更新
显然,解决方案(参见下面的注释)是使用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的输出中去掉所有换行符(实际上是任何非字母)。
一些进一步的事情可能会揭示正在发生的事情:
/tmp/report的脚本:#!/bin/sh ( date;echo "/tmp/report was with args“"$@") report was >> /tmp/output
/tmp/report /tmp/report并验证是否有两行附加到您的monad配置中,使操作为spawn "/tmp/report A"。通过查看预期的行是否被附加到/tmp/output.
liftIO (readProcess "/tmp/report“"B”") >>衍生"/tmp/report A“
(请注意,我们这里使用的是>>,而不是>>=。)当您触发操作时,您应该看到B调用的报告行和A调用的报告行。
根据您在文件/tmp/output中看到的内容,您应该能够确定readProcess命令是否正在执行以及spawn命令是否正在触发。
https://stackoverflow.com/questions/37174160
复制相似问题