dongying9756 2016-08-31 01:44
浏览 216
已采纳

连续两次进入os / exec Command.Start()

I'm trying to use Go's os/exec Command() to simulate a keypress, and sometimes I'll want to use this keypress multiple times in quick succession. I'm using exec.Command to call "xte", "key XF86AudioPlay", which pauses music on a Linux OS. While the Command can Start() or Run() no problem, if I try to execute again, I get an error:

exec: already started

I've tried using Process.Kill() immediately after the execution, in order to free it up, but this will make the execution not work in the first place. I got this idea from here: Terminating a Process Started with os/exec in Golang

My code uses a switch and calls this pause function accordingly, but I'll simply share the basis of the code I wrote, with the case as an example function:

cmd := exec.Command("xte", "key XF86AudioPlay")
//...
func Pause() {
        err := cmd.Start() // or cmd.Run()
        if err != nil {
            fmt.Println(err)
        }
        err = cmd.Process.Kill()
        if err != nil {
            fmt.Printf("Failed to kill: %s", err)
        }
}

So, to recap, I'm successful at calling it one time, but upon success calls to Pause(), I get the error from cmd.Start()/Run() which read: exec: already started.

I also tried going lower, that is, using syscall, but I ran into some trouble. I tried:

args[0] = "xte"
args[1] = "key"
args[2] = "XF86AudioPlay"
//... Pause():
            err := syscall.Exec("/bin", args, os.Environ())
        if err != nil {
            fmt.Println(err)
        }

And here I got a permission denied error, even running as super user (sudo).

How should I proceed call this Command() and then free it up for immediate recall? Or am I on the right track with syscall?

Edit So the solution as both Amd and Son Bui state, was to create the Command everytime I intend to call it, basically putting the assignment cmd := exec.Command()inside my Pause() method.

  • 写回答

2条回答 默认 最新

  • douwen7516 2016-08-31 04:01
    关注

    As the type Cmd struct { Docs said:

    A Cmd cannot be reused after calling its Run, Output or CombinedOutput methods.


    1- Use two separate exec.Command like this,
    Also you may need some delay between runs (simulating two separate keystrokes):

    package main
    
    import (
        "fmt"
        "os"
        "os/exec"
        "time"
    )
    
    func main() {
        Pause()
        fmt.Println("Once")
        time.Sleep(100 * time.Millisecond)
        Pause()
        fmt.Println("Twice")
    }
    func Pause() {
        cmd := exec.Command("xte", "key XF86AudioPlay")
        cmd.Stdout = os.Stdout
        cmd.Stderr = os.Stderr
        err := cmd.Run()
        if err != nil {
            fmt.Println(err)
        }
    }
    

    2- You may run it once:

    You may use something like this (not tested):

    xte 'key XF86AudioPlay' 'key XF86AudioPlay'
    

    and consider adding a short delay to the xte command (simulating two separate keystrokes):

    xte 'key XF86AudioPlay' 'usleep 100000' 'key XF86AudioPlay'
    

    Like this:

    package main
    
    import (
        "fmt"
        "os"
        "os/exec"
    )
    
    func main() {
        Pause()
        fmt.Println("Once")
    }
    func Pause() {
        cmd := exec.Command("xte", `key XF86AudioPlay`, `usleep 100000`, `key XF86AudioPlay`)
        cmd.Stdout = os.Stdout
        cmd.Stderr = os.Stderr
        err := cmd.Run()
        if err != nil {
            fmt.Println(err)
        }
    }
    

    See:

    https://askubuntu.com/questions/499926/why-do-these-xte-commands-work-in-terminal-but-not-when-bound-with-xbindkeys

    http://manpages.ubuntu.com/manpages/wily/man1/xte.1.html

    http://wiki.robotz.com/index.php/Linux_Tools_to_Remap_Keys_and_Mouse_Buttons


    I hope this helps.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 STM32驱动继电器
  • ¥15 Windows server update services
  • ¥15 关于#c语言#的问题:我现在在做一个墨水屏设计,2.9英寸的小屏怎么换4.2英寸大屏
  • ¥15 模糊pid与pid仿真结果几乎一样
  • ¥15 java的GUI的运用
  • ¥15 我想付费需要AKM公司DSP开发资料及相关开发。
  • ¥15 怎么配置广告联盟瀑布流
  • ¥15 Rstudio 保存代码闪退
  • ¥20 win系统的PYQT程序生成的数据如何放入云服务器阿里云window版?
  • ¥50 invest生境质量模块