我如何在xmonad键绑定中使用readProcess的输出? [英] How do I use the output of readProcess in an xmonad keybinding?
问题描述
test = readProcessecho[-n,gvim] []
这会抛出,因为测试返回IO String并且spawn期望一个String。
((modm,xK_y),spawn(xmessage++ test))
确定。这很酷。我知道IO操作是不可预测的,所以应该将它们分开。精细。所以我在网上做了一些尝试,并得到了这个(放弃了xmessage,只想传递测试的输出):
((modm,xK_y),liftIO test>> = spawn)
。它烦人地编译,但当我尝试绑定时没有任何反应。 (我也用spawnxmessage test替换了它),然后工作)
然后,我想也许我的函数有问题,所以我重复它,但从GCHi我得到gvim这是正确的。然后我把它写到haskell文件中:
main = test>> = putStrLn
test = readProcess echo[-n,gvim] []
p>
那么,我出错的地方是什么?
编辑:解决方案是使用
runProcessWithInput
而不是readProcess
。
相关链接: https://ghc.haskell.org/trac/ghc / ticket / 5212 xmonad io binding not working解决方案更新
显然,解决方案)使用readProcessWithInput
原始答案
您说过:
liftIO test>> = spawn
code>不起作用,但如何:
liftIO test>> =(\ m - > spawn(xmessage++ m))
另外请注意,由
readProcess
返回的字符串最后可能会有换行符,这可能会影响事物。
在这种情况下可以尝试更多的事情:
returngvim>> =(\ m - > spawn(xmessage++ m))
import Data.Char
do {m < - liftIO test; spawn(xmessage++(filter isAlpha m))}
第一个应该成功,因为它相当于
spawnxmessage grim
。第二个将从test
的输出中删除任何新行(确实是任何非字母)。
一些进一步的事情可能会揭示发生的事情:
创建一个名为
/ tmp /报告
与这些内容:#!/ bin / sh
(日期;回声/ tmp / report用args调用$ @)>> / tmp / output
制作
/ tmp / report
executable。
- 运行
C $ C>。通过查看预期行是否附加到/ tmp / report
并确认两行附加到<$ c在您的monad配置中,使操作spawn/ tmp / report A$> / tmp / output
/ tmp / output
来测试行为。尝试使单行动为此:liftIO(readProcess/ tmp / report[B])>> spawn/ tmp / report A
(注意我们使用
> >
这里,而不是>> =
。)当你触发这个动作时,你应该看到B
呼叫,也是A
呼叫中的一个。
根据您在文件
/ tmp / output
中看到的内容,您应该能够确定readProcess
命令甚至被执行以及
spawn
命令被触发。Ok, so some time ago I was thinking of basing the effect of a keybinding in my xmonad based on the output of a script on my box. I eventually decided not to do that for unrelated reasons but I did recently try to do something similar just as an exercise in learning Haskell.
So, given the function:
test = readProcess "echo" ["-n", "gvim"] []
This throws up because test returns IO String and spawn expects a String.
((modm, xK_y), spawn ("xmessage " ++ test))
Ok. That's cool. I get it that IO operations are unpredictable and so they should be kept separate. Fine. So I did some poking around online and got to this (dropped the xmessage and just want to pass the output of test by itself):
((modm, xK_y), liftIO test >>= spawn)
This is worse. It annoyingly compiles but nothing happens when I try out the binding. (I also replaced it with just spawn "xmessage test" and that worked)
So, then I thought "Maybe there's something wrong with my function" so I repl it but from GCHi I get "gvim" which is correct. So then I write it to a haskell file:
main = test >>= putStrLn test = readProcess "echo" ["-n", "gvim"] []
Also works correctly.
So, where did I go wrong?
EDIT: Solution was to use
runProcessWithInput
instead ofreadProcess
. Related link: https://ghc.haskell.org/trac/ghc/ticket/5212 xmonad io binding not working解决方案Update
Apparently the solution (see the comments below) is to use
readProcessWithInput
Original Answer
You said that:
liftIO test >>= spawn
didn't work, but how about:
liftIO test >>= (\m -> spawn ("xmessage " ++ m))
Also note that the string returned by
readProcess
likely will have a newline at the end, and that may be affecting things.Some more things to try in this vein:
return "gvim" >>= (\m -> spawn ("xmessage " ++ m)) import Data.Char do { m <- liftIO test; spawn ("xmessage " ++ (filter isAlpha m)) }
The first one should succeed since it is equivalent to
spawn "xmessage grim"
. The second one will strip any newlines (indeed, any non-letters) from the output oftest
.Some further things which might shed light on what is going on:
Create a script called
/tmp/report
with these contents:#!/bin/sh ( date; echo "/tmp/report was called with args" "$@") >> /tmp/output
Make
/tmp/report
executable.- Run
/tmp/report
and verify that two lines was appended to/tmp/output
- In your monad config, make the action
spawn "/tmp/report A"
. Test the action by seeing if the expected line is appended to/tmp/output
.Try making the monad action this:
liftIO (readProcess "/tmp/report" ["B"] "") >> spawn "/tmp/report A"
(Note we are using
>>
here, not>>=
.) When you trigger the action you should see a report line for theB
call and also one for theA
call.Based on what you see in the file
/tmp/output
you should be able to determine whether thereadProcess
command is even being executed as well as thespawn
command is triggering.这篇关于我如何在xmonad键绑定中使用readProcess的输出?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!