我如何在xmonad键绑定中使用readProcess的输出? [英] How do I use the output of readProcess in an xmonad keybinding?

查看:153
本文介绍了我如何在xmonad键绑定中使用readProcess的输出?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

好的,前段时间我正在考虑基于我盒子上脚本输出的xmonad中的键绑定效果。我最终决定不要这样做,因为不相关的原因,但我最近尝试做类似于学习Haskell的练习。

所以,给定函数:

p>

  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 的输出中删除任何新行(确实是任何非字母)。



一些进一步的事情可能会揭示发生的事情:


  1. 创建一个名为 / tmp /报告与这些内容:

     #!/ bin / sh 
    (日期;回声/ tmp / report用args调用$ @)>> / tmp / output


  2. 制作 / tmp / report executable。


  3. 运行 / tmp / report 并确认两行附加到<$ c在您的monad配置中,使操作 spawn/ tmp / report A / tmp / output
  4. C $ C>。通过查看预期行是否附加到 / 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 of readProcess. 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 of test.

Some further things which might shed light on what is going on:

  1. Create a script called /tmp/report with these contents:

    #!/bin/sh
    ( date; echo "/tmp/report was called with args" "$@") >> /tmp/output
    

  2. Make /tmp/report executable.

  3. Run /tmp/report and verify that two lines was appended to /tmp/output
  4. 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.
  5. 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 the B call and also one for the A call.

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.

这篇关于我如何在xmonad键绑定中使用readProcess的输出?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆