doucai9270 2016-09-06 07:04
浏览 68
已采纳

为什么此exec.Command到另一个打开的tty不能正常工作

Can anybody please help me figure out what I'm doing wrong here.

I'm trying to execute a command (opening vim in this case) that runs in a different tty, in this case /dev/ttys001, which is opened in another tab in my terminal.

Running the code below does render vim in /dev/ttys001's window, however, actually typing to stdin from that window doesn't register properly.

Any advice is much appreciated!

package main

import (
    "log"
    "os"
    "os/exec"
)

func main() {
    tty, err := os.OpenFile("/dev/ttys001", os.O_RDWR, os.ModePerm)
    if err != nil {
        log.Fatalln(err)
    }
    defer tty.Close()

    c := exec.Command("vim")
    c.Stdin = tty
    c.Stdout = tty
    c.Stderr = tty
    if err := c.Run(); err != nil {
        log.Fatalln(err)
    }
}

I have also tried setting the command's SysProcAttr field with the following code but receive the error: fork/exec /usr/local/bin/vim: inappropriate ioctl for device.

procAttr := &syscall.SysProcAttr{
    Setpgid:    true,
    Ctty:       int(tty.Fd()),
    Foreground: true,
}
c.SysProcAttr = procAttr

展开全部

  • 写回答

1条回答 默认 最新

  • duan051347 2016-09-07 06:25
    关注

    For anybody who's interested, I came up with a solution, but I ended up having to use system calls instead of the os/exec package's functions.

    package main
    
    import (
        "log"
        "os"
        "syscall"
        "unsafe"
    )
    
    var tty = "/dev/ttys001"
    var cmd = "vim
    "
    
    func main() {
        ttyFile, err := os.Open(tty)
        if err != nil {
            log.Fatalln(err)
        }
        defer ttyFile.Close()
    
        cbs, err := syscall.ByteSliceFromString(cmd)
        if err != nil {
            log.Fatalln(err)
        }
    
        var eno syscall.Errno
        for _, c := range cbs {
            _, _, eno = syscall.Syscall(syscall.SYS_IOCTL,
                ttyFile.Fd(),
                syscall.TIOCSTI,
                uintptr(unsafe.Pointer(&c)),
            )
            if eno != 0 {
                log.Fatalln(eno)
            }
        }
    }
    

    展开全部

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
编辑
预览

报告相同问题?

手机看
程序员都在用的中文IT技术交流社区

程序员都在用的中文IT技术交流社区

专业的中文 IT 技术社区,与千万技术人共成长

专业的中文 IT 技术社区,与千万技术人共成长

关注【CSDN】视频号,行业资讯、技术分享精彩不断,直播好礼送不停!

关注【CSDN】视频号,行业资讯、技术分享精彩不断,直播好礼送不停!

客服 返回
顶部