[英]How do I use the output of readProcess in an xmonad keybinding?
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. 好的,所以前段时间,我正在考虑根据框上脚本的输出,在xmonad中建立键绑定的效果。 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. 我最终出于不相关的原因决定不这样做,但是最近我确实尝试做类似的事情,就像学习Haskell的练习一样。
So, given the function: 因此,给定功能:
test = readProcess "echo" ["-n", "gvim"] []
This throws up because test returns IO String and spawn expects a String. 由于测试返回IO String并生成一个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. 我知道IO操作是不可预测的,因此应将其分开。 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): 所以我在网上做了一些探索(删除了xmessage,只是想自己通过测试的输出):
((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) (我也将其替换为仅生成“ xmessage test”,并且有效)
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. 因此,我当时以为“我的功能也许有问题”,所以我将其替换,但是从GCHi中我得到了“ gvim”,这是正确的。 So then I write it to a haskell file: 因此,我将其写入haskell文件:
main = test >>= putStrLn
test = readProcess "echo" ["-n", "gvim"] []
Also works correctly. 也可以正常工作。
So, where did I go wrong? 那么,我哪里出错了?
EDIT: Solution was to use runProcessWithInput
instead of readProcess
. 编辑:解决方案是使用runProcessWithInput
而不是readProcess
。 Related link: https://ghc.haskell.org/trac/ghc/ticket/5212 xmonad io binding not working 相关链接: https: //ghc.haskell.org/trac/ghc/ticket/5212 xmonad io绑定不起作用
Update 更新资料
Apparently the solution (see the comments below) is to use readProcessWithInput
显然,解决方案(请参阅下面的注释)是使用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. 还要注意, readProcess
返回的字符串可能在末尾有换行符,这可能会影响事情。
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"
. 第一个应该成功,因为它等效于spawn "xmessage grim"
。 The second one will strip any newlines (indeed, any non-letters) from the output of test
. 第二个将从test
的输出中删除所有换行符(实际上,任何非字母)。
Some further things which might shed light on what is going on: 其他一些事情可能会揭示正在发生的事情:
Create a script called /tmp/report
with these contents: 使用以下内容创建一个名为/tmp/report
的脚本:
#!/bin/sh ( date; echo "/tmp/report was called with args" "$@") >> /tmp/output
Make /tmp/report
executable. 使/tmp/report
可执行。
/tmp/report
and verify that two lines was appended to /tmp/output
运行/tmp/report
并验证两行是否附加到/tmp/output
spawn "/tmp/report A"
. 在您的monad配置中,使动作spawn "/tmp/report A"
。 Test the action by seeing if the expected line is appended to /tmp/output
. 通过查看预期行是否附加到/tmp/output
来测试操作。 Try making the monad action this: 尝试执行monad操作:
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 the B
call and also one for the A
call. (请注意,我们使用>>
这里,不是>>=
)。当你触发动作,你应该可以看到一个报告线B
呼叫,还一个是A
电话。
Based on what you see in the file /tmp/output
you should be able to determine whether the readProcess
command is even being executed as well as the spawn
command is triggering. 根据您在文件/tmp/output
看到的内容,您应该能够确定readProcess
命令是否正在执行以及spawn
命令是否正在触发。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.